idnits 2.17.1 draft-melnikov-rfc2192bis-00.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- ** It looks like you're using RFC 3978 boilerplate. You should update this to the boilerplate described in the IETF Trust License Policy document (see https://trustee.ietf.org/license-info), which is required now. -- Found old boilerplate from RFC 3978, Section 5.1 on line 14. -- Found old boilerplate from RFC 3978, Section 5.5 on line 818. -- Found old boilerplate from RFC 3979, Section 5, paragraph 1 on line 789. -- Found old boilerplate from RFC 3979, Section 5, paragraph 2 on line 796. -- Found old boilerplate from RFC 3979, Section 5, paragraph 3 on line 802. ** This document has an original RFC 3978 Section 5.4 Copyright Line, instead of the newer IETF Trust Copyright according to RFC 4748. ** This document has an original RFC 3978 Section 5.5 Disclaimer, instead of the newer disclaimer which includes the IETF Trust according to RFC 4748. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- ** Missing document type: Expected "INTERNET-DRAFT" in the upper left hand corner of the first page ** The document is more than 15 pages and seems to lack a Table of Contents. == The page length should not exceed 58 lines per page, but there was 18 longer pages, the longest (page 2) being 60 lines == It seems as if not all pages are separated by form feeds - found 0 form feeds but 19 pages -- Found 19 instances of the string 'FORMFEED[Page...' -- is this a case of missing nroff postprocessing? Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** The document seems to lack an Introduction section. ** The document seems to lack an IANA Considerations section. (See Section 2.2 of https://www.ietf.org/id-info/checklist for how to handle the case when there are no actions for IANA.) ** There are 6 instances of too long lines in the document, the longest one being 7 characters in excess of 72. ** The abstract seems to contain references ([IMAP4]), which it shouldn't. Please replace those with straight textual mentions of the documents in question. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the RFC 3978 Section 5.4 Copyright Line does not match the current year == The document seems to lack the recommended RFC 2119 boilerplate, even if it appears to use RFC 2119 keywords -- however, there's a paragraph with a matching beginning. Boilerplate error? (The document does seem to have the reference to RFC 2119 which the ID-Checklist requires). -- The document seems to lack a disclaimer for pre-RFC5378 work, but may have content which was first submitted before 10 November 2008. If you have contacted all the original authors and they are all willing to grant the BCP78 rights to the IETF Trust, then this is fine, and you can ignore this comment. If not, you may need to add the pre-RFC5378 disclaimer. (See the Legal Provisions document at https://trustee.ietf.org/license-info for more information.) -- The document date (September 2005) is 6788 days in the past. Is this intentional? -- Found something which looks like a code comment -- if you have code sections in the document, please surround them with '' and '' lines. Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) == Missing Reference: 'UTF8' is mentioned on line 292, but not defined == Missing Reference: 'ABNF' is mentioned on line 410, but not defined -- Looks like a reference, but probably isn't: '256' on line 670 -- Looks like a reference, but probably isn't: '6' on line 575 == Unused Reference: 'UTF-8' is defined on line 510, but no explicit reference was found in the text ** Obsolete normative reference: RFC 3501 (ref. 'IMAP4') (Obsoleted by RFC 9051) -- No information found for draft-melnikov-imap-ext-abnf-XX - is the name correct? -- Possible downref: Normative reference to a draft: ref. 'IMAPABNF' Summary: 10 errors (**), 0 flaws (~~), 7 warnings (==), 13 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 Network Working Group C. Newman 3 Document: draft-melnikov-rfc2192bis-00.txt Sun Microsystems 4 Expires: March 2006 A. Melnikov 5 Intended category: Standards Track Isode Ltd. 6 September 2005 8 IMAP URL Scheme 10 Status of this Memo 11 By submitting this Internet-Draft, each author represents that any 12 applicable patent or other IPR claims of which he or she is aware 13 have been or will be disclosed, and any of which he or she becomes 14 aware will be disclosed, in accordance with Section 6 of BCP 79. 16 Internet-Drafts are working documents of the Internet Engineering 17 Task Force (IETF), its areas, and its working groups. Note that 18 other groups may also distribute working documents as Internet-Drafts. 20 Internet-Drafts are draft documents valid for a maximum of six 21 months and may be updated, replaced, or obsoleted by other documents 22 at any time. It is inappropriate to use Internet-Drafts as reference 23 material or to cite them other than as "work in progress". 25 The list of current Internet-Drafts can be accessed at 26 http://www.ietf.org/ietf/1id-abstracts.txt 28 The list of Internet-Draft Shadow Directories can be accessed at 29 http://www.ietf.org/shadow.html. 31 A revised version of this draft document will be submitted to the RFC 32 editor as a Proposed Standard for the Internet Community. Discussion 33 and suggestions for improvement are requested, and should be sent to 34 the IMAPEXT Mailing list . Distribution of this 35 draft is unlimited. 37 Copyright Notice 39 Copyright (C) The Internet Society (2005). 41 Abstract 43 IMAP [IMAP4] is a rich protocol for accessing remote message 44 stores. It provides an ideal mechanism for accessing public mail- 45 ing list archives as well as private and shared message stores. 47 This document defines a URL scheme for referencing objects on an 48 IMAP server. 50 1. Conventions used in this document 52 The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", and "MAY" 53 in this document are to be interpreted as defined in "Key words for 54 use in RFCs to Indicate Requirement Levels" [KEYWORDS]. 56 2. IMAP scheme 58 The IMAP URL scheme is used to designate IMAP servers, mailboxes, 59 messages, MIME bodies [MIME], and search programs on Internet hosts 60 accessible using the IMAP protocol. 62 The IMAP URL follows the common Internet scheme syntax as defined 63 in [URI-GEN] <>. If : is omitted, the port defaults to 143. 66 An IMAP URL takes one of the following forms: 68 imap:/// 69 imap:///;TYPE= 70 imap:///[uidvalidity][?] 71 imap:///[uidvalidity][isection] 73 The first form is used to refer to an IMAP server, the second form 74 refers to a list of mailboxes, the third form refers to the con- 75 tents of a mailbox or a set of messages resulting from a search, 76 and the final form refers to a specific message or message part. 77 Note that the syntax here is informal. The authoritative formal 78 syntax for IMAP URLs is defined in section 11. 80 3. IMAP User Name and Authentication Mechanism 82 A user name (authorization identity) and/or authentication mecha- 83 nism may be supplied. They are used in the "LOGIN" or "AUTHENTI- 84 CATE" commands after making the connection to the IMAP server. If 85 no user name or authentication mechanism is supplied, the user name 86 "anonymous" is used with the "LOGIN" command and the password is 87 supplied as the Internet e-mail address of the end user accessing 88 the resource. If the URL doesn't supply a user name, the program 89 interpreting the IMAP URL SHOULD request one from the user if nec- 90 essary. 92 <> 94 <> 96 An authentication mechanism can be expressed by adding ";AUTH=" to the end of the user name. When such an is indicated, the client SHOULD request appropriate creden- 99 tials from that mechanism and use the "AUTHENTICATE" command 100 instead of the "LOGIN" command. If no user name is specified, one 101 SHOULD be obtained from the mechanism or requested from the user as 102 appropriate. 104 The string ";AUTH=*" indicates that the client SHOULD select an 105 appropriate authentication mechanism. It MAY use any mechanism 106 listed in the CAPABILITY command or use an out of band security 107 service resulting in a PREAUTH connection. If no user name is 108 specified and no appropriate authentication mechanisms are avail- 109 able, the client SHOULD fall back to anonymous login as described 110 above. This allows a URL which grants read-write access to autho- 111 rized users, and read-only anonymous access to other users. 113 If a user name is included with no authentication mechanism, then 114 ";AUTH=*" is assumed. 116 Since URLs can easily come from untrusted sources, care must be 117 taken when resolving a URL which requires or requests any sort of 118 authentication. If authentication credentials are supplied to the 119 wrong server, it may compromise the security of the user's account. 120 The program resolving the URL should make sure it meets at least 121 one of the following criteria in this case: 123 (1) The URL comes from a trusted source, such as a referral server 124 which the client has validated and trusts according to site policy. 125 Note that user entry of the URL may or may not count as a trusted 126 source, depending on the experience level of the user and site pol- 127 icy. 128 (2) Explicit local site policy permits the client to connect to the 129 server in the URL. For example, if the client knows the site 130 domain name, site policy may dictate that any hostname ending in 131 that domain is trusted. 132 (3) The user confirms that connecting to that domain name with the 133 specified credentials and/or mechanism is permitted. 134 (4) A mechanism is used which validates the server before passing 135 potentially compromising client credentials. <> 136 (5) An authentication mechanism is used which will not reveal 137 information to the server which could be used to compromise future 138 connections. 140 URLs which do not include a user name must be treated with extra 141 care, since they are more likely to compromise the user's primary 142 account. A URL containing ";AUTH=*" must also be treated with 143 extra care since it might fall back on a weaker security mechanism. 144 Finally, clients are discouraged from using a plain text password 145 as a fallback with ";AUTH=*" unless the connection has strong 146 encryption (<>). 148 A program interpreting IMAP URLs MAY cache open connections to an 149 IMAP server for later re-use. If a URL contains a user name, only 150 connections authenticated as that user may be re-used. If a URL 151 does not contain a user name or authentication mechanism, then only 152 an anonymous connection may be re-used. If a URL contains an 153 authentication mechanism without a user name, then any non-anony- 154 mous connection may be re-used. 156 Note that if unsafe or reserved characters such as " " or ";" are 157 present in the user name or authentication mechanism, they MUST be 158 encoded as described in [URI-GEN]. 160 4. IMAP server 162 An IMAP URL referring to an IMAP server has the following form: 164 imap:/// 166 A program interpreting this URL would issue the standard set of 167 commands it uses to present a view of the contents of an IMAP 168 server. This is likely to be semanticly equivalent to one of the 169 following URLs: 171 imap:///;TYPE=LIST 172 imap:///;TYPE=LSUB 174 <> 177 5. Lists of mailboxes 179 An IMAP URL referring to a list of mailboxes has the following 180 form: 182 imap:///;TYPE= 184 The may be either "LIST" or "LSUB", and is case insen- 185 sitive. The field ";TYPE=" MUST be included. 187 The is any argument suitable for the list-mail- 188 box field of the IMAP [IMAP4] LIST or LSUB commands. The field 189 may be omitted, in which case the program inter- 190 preting the IMAP URL may use "*" or "%" as the . 191 The program SHOULD use "%" if it supports a hierarchical view, oth- 192 erwise it SHOULD use "*". 194 Note that if unsafe or reserved characters such as " " or "%" are 195 present in they MUST be encoded as described in 196 [URI-GEN]. If the character "/" is present in enc-list-mailbox, it 197 SHOULD NOT be encoded. 199 6. Lists of messages 201 An IMAP URL referring to a list of messages has the following form: 203 imap:///[uidvalidity][?] 205 The field is used as the argument to the IMAP4 206 "SELECT" command. Note that if unsafe or reserved characters such 207 as " ", ";", or "?" are present in they MUST be 208 encoded as described in [URI-GEN]. If the character "/" is present 209 in enc-mailbox, it SHOULD NOT be encoded. 211 The [uidvalidity] field is optional. If it is present, it MUST be 212 the argument to the IMAP4 UIDVALIDITY status response at the time 213 the URL was created. This SHOULD be used by the program interpret- 214 ing the IMAP URL to determine if the URL is stale. 216 The [?] field is optional. If it is not present, the 217 contents of the mailbox SHOULD be presented by the program inter- 218 preting the URL. If it is present, it SHOULD be used as the argu- 219 ments following an IMAP4 SEARCH command with unsafe characters such 220 as " " (which are likely to be present in the ) encoded 221 as described in [URI-GEN]. 223 7. A specific message or message part 225 An IMAP URL referring to a specific message or message part has the 226 following form: 228 imap:///[uidvalidity][isection] 230 The and [uidvalidity] are as defined above. 232 If [uidvalidity] is present in this form, it SHOULD be used by the 233 program interpreting the URL to determine if the URL is stale. 235 The refers to an IMAP4 message UID, and SHOULD be used as 236 the argument to the IMAP4 "UID FETCH" command. 238 The [isection] field is optional. If not present, the URL refers 239 to the entire Internet message as returned by the IMAP command "UID 240 FETCH BODY.PEEK[]". If present, the URL refers to the object 241 returned by a "UID FETCH BODY.PEEK[
]" command. The 242 type of the object may be determined with a "UID FETCH BODYS- 243 TRUCTURE" command and locating the appropriate part in the result- 244 ing BODYSTRUCTURE. Note that unsafe characters in [isection] MUST 245 be encoded as described in [URI-GEN]. 247 8. Relative IMAP URLs 249 Relative IMAP URLs are permitted and are resolved according to the 250 rules defined in [URI-GEN] with one exception. In IMAP URLs, 251 parameters are treated as part of the normal path with respect to 252 relative URL resolution. This is believed to be the behavior of 253 the installed base and is likely to be documented in a future revi- 254 sion of the relative URL specification. 256 The following observations are also important: 258 The grammar element is considered part of the user name for 259 purposes of resolving relative IMAP URLs. This means that unless a 260 new login/server specification is included in the relative URL, the 261 authentication mechanism is inherited from a base IMAP URL. 263 URLs always use "/" as the hierarchy delimiter for the purpose of 264 resolving paths in relative URLs. IMAP4 permits the use of any 265 hierarchy delimiter in mailbox names. For this reason, relative 266 mailbox paths will only work if the mailbox uses "/" as the hierar- 267 chy delimiter. Relative URLs may be used on mailboxes which use 268 other delimiters, but in that case, the entire mailbox name MUST be 269 specified in the relative URL or inherited as a whole from the base 270 URL. 272 The base URL for a list of mailboxes or messages which was referred 273 to by an IMAP URL is always the referring IMAP URL itself. The 274 base URL for a message or message part which was referred to by an 275 IMAP URL may be more complicated to determine. The program inter- 276 preting the relative URL will have to check the headers of the MIME 277 entity and any enclosing MIME entities in order to locate the "Con- 278 tent-Base" and "Content-Location" headers. These headers are used 279 to determine the base URL as defined in <<[HTTP]>>. For example, 280 if the referring IMAP URL contains a "/;SECTION=1.2" parameter, 281 then the MIME headers for section 1.2, for section 1, and for the 282 enclosing message itself SHOULD be checked in that order for "Con- 283 tent-Base" or "Content-Location" headers. 285 9. Multinational Considerations 287 IMAP4 [IMAP4] section 5.1.3 includes a convention for encoding non- 288 US-ASCII characters in IMAP mailbox names. Because this convention 289 is private to IMAP, it is necessary to convert IMAP's encoding to 290 one that can be more easily interpreted by a URL display program. 291 For this reason, IMAP's modified UTF-7 encoding for mailboxes MUST 292 be converted to UTF-8 [UTF8]. Since 8-bit characters are not per- 293 mitted in URLs, the UTF-8 characters are encoded as required by the 294 URL specification [URI-GEN]. Sample code is included in Appendix A 295 to demonstrate this conversion. 297 10. Examples 299 The following examples demonstrate how an IMAP4 client program 300 might translate various IMAP4 URLs into a series of IMAP4 commands. 301 Commands sent from the client to the server are prefixed with "C:", 302 and responses sent from the server to the client are prefixed with 303 "S:". 305 The URL: 307 309 Results in the following client commands: 311 312 C: A001 LOGIN ANONYMOUS sheridan@babylon5.example.org 313 C: A002 SELECT gray-council 314 315 C: A003 UID FETCH 20 BODY.PEEK[] 317 The URL: 319 321 Results in the following client commands: 323 324 325 C: A001 LOGIN MICHAEL zipper 326 C: A002 LIST "" users.* 328 The URL: 330 333 Results in the following client commands: 335 336 C: A001 LOGIN ANONYMOUS bester@psycop.psicorp.example.org 337 C: A002 SELECT ~peter/&ZeVnLIqe-/&U,BTFw- 338 340 The URL: 342 345 Results in the following client commands: 347 348 C: A001 AUTHENTICATE GSSAPI 349 350 C: A002 SELECT gray-council 351 C: A003 UID FETCH 20 BODY.PEEK[1.2] 353 If the following relative URL is located in that body part: 355 <;section=1.4> 357 This could result in the following client commands: 359 C: A004 UID FETCH 20 (BODY.PEEK[1.2.MIME] 360 BODY.PEEK[1.MIME] 361 BODY.PEEK[HEADER.FIELDS (Content-Base Content-Location)]) 362 364 C: A005 UID FETCH 20 BODY.PEEK[1.4] 366 The URL: 368 370 Could result in the following: 372 373 C: A001 CAPABILITY 374 S: * CAPABILITY IMAP4rev1 AUTH=DIGEST-MD5 375 S: A001 OK 376 C: A002 AUTHENTICATE DIGEST-MD5 377 378 S: A002 OK user lennier authenticated 379 C: A003 SELECT "gray council" 380 ... 381 C: A004 SEARCH SUBJECT shadows 382 S: * SEARCH 8 10 13 14 15 16 383 S: A004 OK SEARCH completed 384 C: A005 FETCH 8,10,13:16 ALL 385 ... 387 NOTE: In this final example, the client has implementation depen- 388 dent choices. The authentication mechanism could be anything, 389 including PREAUTH. And the final FETCH command could fetch more or 390 less information about the messages, depending on what it wishes to 391 display to the user. 393 11. Security Considerations 395 Security considerations discussed in the IMAP specification [IMAP4] 396 and the URL specification <<[BASIC-URL]>> are relevant. Security 397 considerations related to authenticated URLs are discussed in sec- 398 tion 3 of this document. 400 Many email clients store the plain text password for later use 401 after logging into an IMAP server. Such clients MUST NOT use a 402 stored password in response to an IMAP URL without explicit permis- 403 sion from the user to supply that password to the specified host 404 name. 406 12. ABNF for IMAP URL scheme 408 Formal syntax is defined using ABNF [ABNF], extending the ABNF 409 rules in section 9 of [IMAP4]. Elements not defined here can be 410 found in the [ABNF], [IMAP4], [IMAPABNF] or [URI-GEN]. Strings are 411 not case sensitive and free insertion of linear-white-space is not 412 permitted. 414 uchar = unreserved | pct-encoded 415 <> 417 achar = uchar / "&" / "=" 419 bchar = achar / ":" / "@" / "/" 421 <> 425 enc-auth-type = 1*achar 426 ; encoded version of [IMAP4] "auth-type" 428 enc-list-mailbox = 1*bchar 429 ; encoded version of [IMAP4] "list-mailbox" 431 enc-mailbox = 1*bchar 432 ; encoded version of [IMAP4] "mailbox" 434 enc-search = 1*bchar 435 ; encoded version of [IMAPABNF] "search-program". 436 ; Note that IMAP4 literals may not be used 437 ; in a "search-program". 439 enc-section = 1*bchar 440 ; encoded version of [IMAP4] "section-spec" 442 enc-user = 1*achar 443 ; encoded version of [IMAP4] "userid" 445 imapurl = "imap://" iserver "/" [ icommand ] 447 iauth = ";AUTH=" ( "*" / enc-auth-type ) 449 icommand = imailboxlist / imessagelist / imessagepart 451 imailboxlist = [enc-list-mailbox] ";TYPE=" list-type 453 imailbox-ref = enc-mailbox [uidvalidity] 454 ; <> 456 imessagelist = imailbox-ref [ "?" enc-search ] 457 ; "enc-search" is [URI-GEN] "query". 459 imessagepart = imailbox-ref iuid [isection] 461 isection = "/;SECTION=" enc-section 463 iserver = [iuserauth "@"] host [ ":" port ] 464 ; This is the same as "authority" defined in 465 ; [URI-GEN]. See [URI-GEN] for "host" and 466 ; "port" definitions. 467 <> 469 iuid = "/;UID=" nz-number 470 ; See [IMAP4] for "nz-number" definition 472 iuserauth = enc-user [iauth] / [enc-user] iauth 473 ; conforms to the generic syntax of "userinfo" 474 ; as defined in [URI-GEN]. 476 list-type = "LIST" / "LSUB" 478 uidvalidity = ";UIDVALIDITY=" nz-number 479 ; See [IMAP4] for "nz-number" definition 481 13. Normative References 483 <<[BASIC-URL] Berners-Lee, Masinter, McCahill, "Uniform Resource 484 Locators (URL)", RFC 1738, CERN, Xerox Corporation, University of 485 Minnesota, December 1994.>> 487 [KEYWORDS] Bradner, "Key words for use in RFCs to Indicate Require- 488 ment Levels", RFC 2119, Harvard University, March 1997. 490 [IMAP4] Crispin, M., "Internet Message Access Protocol - Version 491 4rev1", RFC 3501, University of Washington, March 2003. 493 [IMAPABNF] Melnikov, A., and C. Daboo, "Collected extensions to 494 IMAP4 ABNF", work in progress, draft-melnikov-imap-ext-abnf-XX.txt. 496 <<[HTTP] Fielding, Gettys, Mogul, Frystyk, Berners-Lee, "Hypertext 497 Transfer Protocol -- HTTP/1.1", RFC 2068, UC Irvine, DEC, MIT/LCS, 498 January 1997.>> 500 <<[ABNF] Crocker, Overell, "Augmented BNF for Syntax Specifica- 501 tions: ABNF", RFC 2234, Internet Mail Consortium, Demon Internet 502 Ltd, November 1997.>> 504 [MIME] Freed, N., Borenstein, N., "Multipurpose Internet Mail 505 Extensions", RFC 2045, Innosoft, First Virtual, November 1996. 507 [URI-GEN] Berners-Lee, T., Fielding, R. and L. Masinter, "Uniform 508 Resource Identifier (URI): Generic Syntax", RFC 3986, January 2005. 510 [UTF-8] Yergeau, F., "UTF-8, a transformation format of ISO 511 10646", STD 63, RFC 3629, November 2003. 513 14. Author's Address 515 Chris Newman 516 Sun Microsystems 517 1050 Lakes Drive 518 West Covina, CA 91790 USA 519 EMail: chris.newman@sun.com 521 Alexey Melnikov 522 Isode Limited 523 5 Castle Business Village 524 36 Station Road 525 Hampton, Middlesex 526 TW12 2BX, UK 527 Email: Alexey.Melnikov@isode.com 528 URI: http://www.melnikov.ca/ 530 Appendix A. Sample code 532 Here is sample C source code to convert between URL paths and IMAP mail- 533 box names, taking into account mapping between IMAP's modified UTF-7 534 [IMAP4] and hex-encoded UTF-8 which is more appropriate for URLs. This 535 code has not been rigorously tested nor does it necessarily behave rea- 536 sonably with invalid input, but it should serve as a useful example. 537 This code just converts the mailbox portion of the URL and does not deal 538 with parameters, query or server components of the URL. 540 <> 542 #include 543 #include 545 /* hexadecimal lookup table */ 546 static char hex[] = "0123456789ABCDEF"; 548 /* URL unsafe printable characters */ 549 static char urlunsafe[] = " \"#%&+:;<=>?@[\\]^`{|}"; 551 /* UTF7 modified base64 alphabet */ 552 static char base64chars[] = 553 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,"; 554 #define UNDEFINED 64 556 /* UTF16 definitions */ 557 #define UTF16MASK 0x03FFUL 558 #define UTF16SHIFT 10 559 #define UTF16BASE 0x10000UL 560 #define UTF16HIGHSTART 0xD800UL 561 #define UTF16HIGHEND 0xDBFFUL 562 #define UTF16LOSTART 0xDC00UL 563 #define UTF16LOEND 0xDFFFUL 565 /* Convert an IMAP mailbox to a URL path 566 * dst needs to have roughly 4 times the storage space of src 567 * Hex encoding can triple the size of the input 568 * UTF-7 can be slightly denser than UTF-8 569 * (worst case: 8 octets UTF-7 becomes 9 octets UTF-8) 570 */ 571 void MailboxToURL(char *dst, char *src) 572 { 573 unsigned char c, i, bitcount; 574 unsigned long ucs4, utf16, bitbuf; 575 unsigned char base64[256], utf8[6]; 577 /* initialize modified base64 decoding table */ 578 memset(base64, UNDEFINED, sizeof (base64)); 579 for (i = 0; i < sizeof (base64chars); ++i) { 580 base64[base64chars[i]] = i; 581 } 583 /* loop until end of string */ 584 while (*src != '\0') { 585 c = *src++; 586 /* deal with literal characters and &- */ 587 if (c != '&' || *src == '-') { 588 if (c < ' ' || c > '~' || strchr(urlunsafe, c) != NULL) { 589 /* hex encode if necessary */ 590 dst[0] = '%'; 591 dst[1] = hex[c >> 4]; 592 dst[2] = hex[c & 0x0f]; 593 dst += 3; 594 } else { 595 /* encode literally */ 596 *dst++ = c; 597 } 598 /* skip over the '-' if this is an &- sequence */ 599 if (c == '&') ++src; 600 } else { 601 /* convert modified UTF-7 -> UTF-16 -> UCS-4 -> UTF-8 -> HEX */ 602 bitbuf = 0; 603 bitcount = 0; 604 ucs4 = 0; 605 while ((c = base64[(unsigned char) *src]) != UNDEFINED) { 606 ++src; 607 bitbuf = (bitbuf << 6) | c; 608 bitcount += 6; 609 /* enough bits for a UTF-16 character? */ 610 if (bitcount >= 16) { 611 bitcount -= 16; 612 utf16 = (bitcount ? bitbuf >> bitcount 613 : bitbuf) & 0xffff; 614 /* convert UTF16 to UCS4 */ 615 if 616 (utf16 >= UTF16HIGHSTART && utf16 <= UTF16HIGHEND) { 617 ucs4 = (utf16 - UTF16HIGHSTART) << UTF16SHIFT; 618 continue; 619 } else if 620 (utf16 >= UTF16LOSTART && utf16 <= UTF16LOEND) { 621 ucs4 += utf16 - UTF16LOSTART + UTF16BASE; 622 } else { 623 ucs4 = utf16; 624 } 625 /* convert UTF-16 range of UCS4 to UTF-8 */ 626 if (ucs4 <= 0x7fUL) { 627 utf8[0] = ucs4; 628 i = 1; 629 } else if (ucs4 <= 0x7ffUL) { 630 utf8[0] = 0xc0 | (ucs4 >> 6); 631 utf8[1] = 0x80 | (ucs4 & 0x3f); 632 i = 2; 633 } else if (ucs4 <= 0xffffUL) { 634 utf8[0] = 0xe0 | (ucs4 >> 12); 635 utf8[1] = 0x80 | ((ucs4 >> 6) & 0x3f); 636 utf8[2] = 0x80 | (ucs4 & 0x3f); 637 i = 3; 638 } else { 639 utf8[0] = 0xf0 | (ucs4 >> 18); 640 utf8[1] = 0x80 | ((ucs4 >> 12) & 0x3f); 641 utf8[2] = 0x80 | ((ucs4 >> 6) & 0x3f); 642 utf8[3] = 0x80 | (ucs4 & 0x3f); 643 i = 4; 644 } 645 /* convert utf8 to hex */ 646 for (c = 0; c < i; ++c) { 647 dst[0] = '%'; 648 dst[1] = hex[utf8[c] >> 4]; 649 dst[2] = hex[utf8[c] & 0x0f]; 650 dst += 3; 651 } 652 } 653 } 654 /* skip over trailing '-' in modified UTF-7 encoding */ 655 if (*src == '-') ++src; 656 } 657 } 658 /* terminate destination string */ 659 *dst = '\0'; 660 } 662 /* Convert hex coded UTF-8 URL path to modified UTF-7 IMAP mailbox 663 * dst should be about twice the length of src to deal with non-hex 664 * coded URLs 665 */ 666 void URLtoMailbox(char *dst, char *src) 667 { 668 unsigned int utf8pos, utf8total, i, c, utf7mode, bitstogo, utf16flag; 669 unsigned long ucs4, bitbuf; 670 unsigned char hextab[256]; 671 /* initialize hex lookup table */ 672 memset(hextab, 0, sizeof (hextab)); 673 for (i = 0; i < sizeof (hex); ++i) { 674 hextab[hex[i]] = i; 675 if (isupper(hex[i])) hextab[tolower(hex[i])] = i; 676 } 678 utf7mode = 0; 679 utf8total = 0; 680 bitstogo = 0; 681 while ((c = *src) != '\0') { 682 ++src; 683 /* undo hex-encoding */ 684 if (c == '%' && src[0] != '\0' && src[1] != '\0') { 685 c = (hextab[src[0]] << 4) | hextab[src[1]]; 686 src += 2; 687 } 688 /* normal character? */ 689 if (c >= ' ' && c <= '~') { 690 /* switch out of UTF-7 mode */ 691 if (utf7mode) { 692 if (bitstogo) { 693 *dst++ = base64chars[(bitbuf << (6 - bitstogo)) & 0x3F]; 694 } 695 *dst++ = '-'; 696 utf7mode = 0; 697 } 698 *dst++ = c; 699 /* encode '&' as '&-' */ 700 if (c == '&') { 701 *dst++ = '-'; 702 } 703 continue; 704 } 705 /* switch to UTF-7 mode */ 706 if (!utf7mode) { 707 *dst++ = '&'; 708 utf7mode = 1; 709 } 710 /* Encode US-ASCII characters as themselves */ 711 if (c < 0x80) { 712 ucs4 = c; 713 utf8total = 1; 714 } else if (utf8total) { 715 /* save UTF8 bits into UCS4 */ 716 ucs4 = (ucs4 << 6) | (c & 0x3FUL); 717 if (++utf8pos < utf8total) { 718 continue; 720 } 721 } else { 722 utf8pos = 1; 723 if (c < 0xE0) { 724 utf8total = 2; 725 ucs4 = c & 0x1F; 726 } else if (c < 0xF0) { 727 utf8total = 3; 728 ucs4 = c & 0x0F; 729 } else { 730 /* NOTE: can't convert UTF8 sequences longer than 4 */ 731 utf8total = 4; 732 ucs4 = c & 0x03; 733 } 734 continue; 735 } 736 /* loop to split ucs4 into two utf16 chars if necessary */ 737 utf8total = 0; 738 do { 739 if (ucs4 >= UTF16BASE) { 740 ucs4 -= UTF16BASE; 741 bitbuf = (bitbuf << 16) | ((ucs4 >> UTF16SHIFT) 742 + UTF16HIGHSTART); 743 ucs4 = (ucs4 & UTF16MASK) + UTF16LOSTART; 744 utf16flag = 1; 745 } else { 746 bitbuf = (bitbuf << 16) | ucs4; 747 utf16flag = 0; 748 } 749 bitstogo += 16; 750 /* spew out base64 */ 751 while (bitstogo >= 6) { 752 bitstogo -= 6; 753 *dst++ = base64chars[(bitstogo ? (bitbuf >> bitstogo) 754 : bitbuf) 755 & 0x3F]; 756 } 757 } while (utf16flag); 758 } 759 /* if in UTF-7 mode, finish in ASCII */ 760 if (utf7mode) { 761 if (bitstogo) { 762 *dst++ = base64chars[(bitbuf << (6 - bitstogo)) & 0x3F]; 763 } 764 *dst++ = '-'; 765 } 766 /* tie off string */ 767 *dst = '\0'; 769 } 771 Appendix B. List of changes since RFC 2192 773 Updated boilerplate, list of editor's, etc. 774 Updated references. 775 Updated ABNF not to use _, to use SP instead of SPACE. 776 Updated example domains to use example.org. 777 Fixed ABNF error in "imessagelist" non-terminal. 778 Updated ABNF, due to changes in RFC 3501, IMAPABNF and RFC 3986. 780 Intellectual Property 782 The IETF takes no position regarding the validity or scope of any 783 Intellectual Property Rights or other rights that might be claimed 784 to pertain to the implementation or use of the technology 785 described in this document or the extent to which any license 786 under such rights might or might not be available; nor does it 787 represent that it has made any independent effort to identify any 788 such rights. Information on the procedures with respect to rights 789 in RFC documents can be found in BCP 78 and BCP 79. 791 Copies of IPR disclosures made to the IETF Secretariat and any 792 assurances of licenses to be made available, or the result of an 793 attempt made to obtain a general license or permission for the use 794 of such proprietary rights by implementers or users of this 795 specification can be obtained from the IETF on-line IPR repository 796 at http://www.ietf.org/ipr. 798 The IETF invites any interested party to bring to its attention 799 any copyrights, patents or patent applications, or other 800 proprietary rights that may cover technology that may be required 801 to implement this standard. Please address the information to the 802 IETF at ietf-ipr@ietf.org. 804 Full Copyright Statement 806 Copyright (C) The Internet Society (2005). 808 This document is subject to the rights, licenses and restrictions 809 contained in BCP 78, and except as set forth therein, the authors 810 retain all their rights. 812 This document and the information contained herein are provided on an 813 "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS 814 OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET 815 ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, 816 INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE 817 INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED 818 WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 820 Acknowledgement 822 Funding for the RFC Editor function is currently provided by the 823 Internet Society.