idnits 2.17.1 draft-ietf-xmpp-6122bis-18.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- No issues found here. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (December 2, 2014) is 3434 days in the past. Is this intentional? Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) == Outdated reference: A later version (-23) exists of draft-ietf-precis-framework-20 == Outdated reference: A later version (-18) exists of draft-ietf-precis-saslprepbis-11 -- Possible downref: Non-RFC (?) normative reference: ref. 'UNICODE' -- Possible downref: Non-RFC (?) normative reference: ref. 'UTR36' == Outdated reference: A later version (-19) exists of draft-ietf-precis-nickname-13 -- Obsolete informational reference (is this intentional?): RFC 3454 (Obsoleted by RFC 7564) -- Obsolete informational reference (is this intentional?): RFC 3490 (Obsoleted by RFC 5890, RFC 5891) -- Obsolete informational reference (is this intentional?): RFC 3920 (Obsoleted by RFC 6120) -- Obsolete informational reference (is this intentional?): RFC 3921 (Obsoleted by RFC 6121) -- Obsolete informational reference (is this intentional?): RFC 4013 (Obsoleted by RFC 7613) -- Obsolete informational reference (is this intentional?): RFC 6122 (Obsoleted by RFC 7622) Summary: 0 errors (**), 0 flaws (~~), 4 warnings (==), 9 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 XMPP P. Saint-Andre 3 Internet-Draft &yet 4 Obsoletes: 6122 (if approved) December 2, 2014 5 Intended status: Standards Track 6 Expires: June 5, 2015 8 Extensible Messaging and Presence Protocol (XMPP): Address Format 9 draft-ietf-xmpp-6122bis-18 11 Abstract 13 This document defines the address format for the Extensible Messaging 14 and Presence Protocol (XMPP), including support for code points 15 outside the ASCII range. This document obsoletes RFC 6122. 17 Status of This Memo 19 This Internet-Draft is submitted in full conformance with the 20 provisions of BCP 78 and BCP 79. 22 Internet-Drafts are working documents of the Internet Engineering 23 Task Force (IETF). Note that other groups may also distribute 24 working documents as Internet-Drafts. The list of current Internet- 25 Drafts is at http://datatracker.ietf.org/drafts/current/. 27 Internet-Drafts are draft documents valid for a maximum of six months 28 and may be updated, replaced, or obsoleted by other documents at any 29 time. It is inappropriate to use Internet-Drafts as reference 30 material or to cite them other than as "work in progress." 32 This Internet-Draft will expire on June 5, 2015. 34 Copyright Notice 36 Copyright (c) 2014 IETF Trust and the persons identified as the 37 document authors. All rights reserved. 39 This document is subject to BCP 78 and the IETF Trust's Legal 40 Provisions Relating to IETF Documents 41 (http://trustee.ietf.org/license-info) in effect on the date of 42 publication of this document. Please review these documents 43 carefully, as they describe your rights and restrictions with respect 44 to this document. Code Components extracted from this document must 45 include Simplified BSD License text as described in Section 4.e of 46 the Trust Legal Provisions and are provided without warranty as 47 described in the Simplified BSD License. 49 Table of Contents 51 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 52 2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 3 53 3. Addresses . . . . . . . . . . . . . . . . . . . . . . . . . . 3 54 3.1. Fundamentals . . . . . . . . . . . . . . . . . . . . . . 3 55 3.2. Domainpart . . . . . . . . . . . . . . . . . . . . . . . 5 56 3.2.1. Preparation . . . . . . . . . . . . . . . . . . . . . 6 57 3.2.2. Enforcement . . . . . . . . . . . . . . . . . . . . . 6 58 3.2.3. Comparison . . . . . . . . . . . . . . . . . . . . . 7 59 3.3. Localpart . . . . . . . . . . . . . . . . . . . . . . . . 7 60 3.3.1. Further Excluded Characters . . . . . . . . . . . . . 7 61 3.4. Resourcepart . . . . . . . . . . . . . . . . . . . . . . 8 62 3.4.1. Applicability to XMPP . . . . . . . . . . . . . . . . 9 63 3.5. Examples . . . . . . . . . . . . . . . . . . . . . . . . 9 64 4. Enforcement in JIDs and JID Parts . . . . . . . . . . . . . . 12 65 5. Internationalization Considerations . . . . . . . . . . . . . 14 66 6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 15 67 6.1. Stringprep Profiles Registry . . . . . . . . . . . . . . 15 68 7. Security Considerations . . . . . . . . . . . . . . . . . . . 15 69 7.1. Reuse of PRECIS . . . . . . . . . . . . . . . . . . . . . 15 70 7.2. Reuse of Unicode . . . . . . . . . . . . . . . . . . . . 15 71 7.3. Address Spoofing . . . . . . . . . . . . . . . . . . . . 15 72 7.3.1. Address Forging . . . . . . . . . . . . . . . . . . . 15 73 7.3.2. Address Mimicking . . . . . . . . . . . . . . . . . . 16 74 8. Conformance Requirements . . . . . . . . . . . . . . . . . . 17 75 9. References . . . . . . . . . . . . . . . . . . . . . . . . . 19 76 9.1. Normative References . . . . . . . . . . . . . . . . . . 19 77 9.2. Informative References . . . . . . . . . . . . . . . . . 20 78 Appendix A. Differences from RFC 6122 . . . . . . . . . . . . . 24 79 Appendix B. Acknowledgements . . . . . . . . . . . . . . . . . . 24 80 Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 24 82 1. Introduction 84 The Extensible Messaging and Presence Protocol (XMPP) [RFC6120] is an 85 application profile of the Extensible Markup Language [XML] for 86 streaming XML data in close to real time between any two or more 87 network-aware entities. The address format for XMPP entities was 88 originally developed in the Jabber open-source community in 1999, 89 first described by [XEP-0029] in 2002, and then defined canonically 90 by [RFC3920] in 2004 and [RFC6122] in 2011. 92 As specified in RFC 3920 and RFC 6122, the XMPP address format used 93 the "stringprep" technology for preparation and comparison of non- 94 ASCII characters [RFC3454]. Following the migration of 95 internationalized domain names away from stringprep, this document 96 defines the XMPP address format in a way that no longer depends on 97 stringprep (see the PRECIS problem statement [RFC6885]). Instead, 98 this document builds upon the internationalization framework defined 99 by the IETF's PRECIS Working Group [I-D.ietf-precis-framework]. 101 Although every attempt has been made to ensure that the characters 102 allowed in Jabber Identifiers (JIDs) under Stringprep are still 103 allowed and handled in the same way under PRECIS, there is no 104 guarantee of strict backward compatibility because of changes in 105 Unicode and the fact that PRECIS handling is based on Unicode 106 properties, not a hardcoded table of characters. Because it is 107 possible that previously-valid JIDs might no longer be valid (or 108 previously-invalid JIDs might now be valid), operators of XMPP 109 services are advised to perform careful testing before migrating 110 accounts and other data. 112 This document obsoletes RFC 6122. 114 2. Terminology 116 Many important terms used in this document are defined in 117 [I-D.ietf-precis-framework], [RFC5890], [RFC6120], [RFC6365], and 118 [UNICODE]. 120 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 121 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 122 "OPTIONAL" in this document are to be interpreted as described in 123 [RFC2119]. 125 3. Addresses 127 3.1. Fundamentals 129 An XMPP entity is anything that can communicate using XMPP. For 130 historical reasons, the network address of an XMPP entity is called a 131 Jabber Identifier ("JID"). A valid JID is a string of Unicode code 132 points [UNICODE], encoded using UTF-8 [RFC3629], and structured as an 133 ordered sequence of localpart, domainpart, and resourcepart, where 134 the first two parts are demarcated by the '@' character used as a 135 separator and the last two parts are similarly demarcated by the '/' 136 character (e.g., ). 138 The syntax for a JID is defined as follows using the Augmented 139 Backus-Naur Form (ABNF) as specified in [RFC5234]. 141 jid = [ localpart "@" ] domainpart [ "/" resourcepart ] 142 localpart = 1*1023(userbyte) 143 ; 144 ; a "userbyte" is a byte used to represent a 145 ; UTF-8 encoded Unicode code point that can be 146 ; contained in a string that conforms to the 147 ; "UsernameCaseMapped" profile of the PRECIS 148 ; IdentifierClass 149 ; 150 domainpart = IP-literal / IPv4address / ifqdn 151 ; 152 ; the "IPv4address" and "IP-literal" rules are 153 ; defined in RFC 3986, and the first-match-wins 154 ; (a.k.a. "greedy") algorithm described therein 155 ; applies to the matching process 156 ; 157 ; note well that reuse of the IP-literal rule from 158 ; RFC 3986 implies that IPv6 addresses are enclosed 159 ; in square brackets (i.e., beginning with '[' and 160 ; ending with ']') 161 ; 162 ifqdn = 1*1023(domainbyte) 163 ; 164 ; a "domainbyte" is a byte used to represent a 165 ; UTF-8 encoded Unicode code point that can be 166 ; contained in a string that conforms to RFC 5890 167 ; 168 resourcepart = 1*1023(resourcebyte) 169 ; 170 ; an "opaquebyte" is a byte used to represent a 171 ; UTF-8 encoded Unicode code point that can be 172 ; contained in a string that conforms to the 173 ; "OpaqueString" profile of the PRECIS 174 ; FreeformClass 175 ; 177 All JIDs are based on the foregoing structure. However, note that 178 the formal syntax provided above does not capture all of the rules 179 and restrictions that apply to JIDs, which are described below. 181 Each allowable portion of a JID (localpart, domainpart, and 182 resourcepart) MUST NOT be zero octets in length and MUST NOT be more 183 than 1023 octets in length, resulting in a maximum total size 184 (including the '@' and '/' separators) of 3071 octets. 186 Implementation Note: The length limits on JIDs and parts of JIDs 187 are based on octets (bytes), not characters. UTF-8 encoding can 188 result in more than one octet per character. 190 Implementation Note: When dividing a JID into its component parts, 191 an implementation needs to match the separator characters '@' and 192 '/' before applying any transformation algorithms, which might 193 decompose certain Unicode code points to the separator characters 194 (e.g., under Unicode Normalization Form KC U+FE6B SMALL COMMERCIAL 195 AT decomposes to U+0040 COMMERCIAL AT, although note that this 196 decomposition does not occur under Unicode Normalization Form C, 197 which is used in this specification). 199 This document defines the native format for JIDs; see [RFC5122] for 200 information about the representation of a JID as a Uniform Resource 201 Identifier (URI) [RFC3986] or Internationalized Resource Identifier 202 (IRI) [RFC3987] and the extraction of a JID from an XMPP URI or IRI. 204 3.2. Domainpart 206 The domainpart of a JID is that portion after the first '@' character 207 (if any) and before the first '/' character (if any); it is the 208 primary identifier and is the only REQUIRED element of a JID (a mere 209 domainpart is a valid JID). Typically a domainpart identifies the 210 "home" server to which clients connect for XML routing and data 211 management functionality. However, it is not necessary for an XMPP 212 domainpart to identify an entity that provides core XMPP server 213 functionality (e.g., a domainpart can identify an entity such as a 214 multi-user chat service [XEP-0045], a publish-subscribe service 215 [XEP-0060], or a user directory). 217 The domainpart for every XMPP service MUST be a fully-qualified 218 domain name (FQDN), an IPv4 address, an IPv6 address, or an 219 unqualified hostname (i.e., a text label that is resolvable on a 220 local network). 222 Informational Note: The term "fully-qualified domain name" is not 223 well defined. In [RFC1034] it is also called an absolute domain 224 name, and the two terms are associated in [RFC1535]. The earliest 225 use of the term can be found in [RFC1123]. References to those 226 older specifications ought not to be construed as limiting the 227 characters of a fully-qualified domain name to the ASCII range; 228 for example, [RFC5890] mentions that a fully-qualified domain name 229 can contain one or more U-labels. 231 Interoperability Note: Domainparts that are IP addresses might not 232 be accepted by other services for the purpose of server-to-server 233 communication, and domainparts that are unqualified hostnames 234 cannot be used on public networks because they are resolvable only 235 on a local network. 237 If the domainpart includes a final character considered to be a label 238 separator (dot) by [RFC1034], this character MUST be stripped from 239 the domainpart before the JID of which it is a part is used for the 240 purpose of routing an XML stanza, comparing against another JID, or 241 constructing an XMPP URI or IRI [RFC5122]. In particular, such a 242 character MUST be stripped before any other canonicalization steps 243 are taken. 245 In general, the content of a domainpart is an Internationalized 246 Domain Name ("IDN") as described in the specifications for 247 Internationalized Domain Names in Applications (commonly called 248 "IDNA2008"), and a domainpart is an "IDNA-aware domain name slot" as 249 defined in [RFC5890]. 251 After any and all normalization, conversion, and mapping of code 252 points as well as encoding of the string as UTF-8, a domainpart MUST 253 NOT be zero octets in length and MUST NOT be more than 1023 octets in 254 length. (Naturally, the length limits of [RFC1034] apply, and 255 nothing in this document is to be interpreted as overriding those 256 more fundamental limits.) 258 Detailed rules and considerations for preparation, enforcement, and 259 comparison are provided in the following sections. 261 3.2.1. Preparation 263 An entity that prepares a string for inclusion in an XMPP domainpart 264 slot MUST ensure that the string consists only of Unicode code points 265 that are allowed in NR-LDH labels or U-labels as defined in 266 [RFC5890]. This implies that the string MUST NOT include A-labels as 267 defined in [RFC5890]; each A-label MUST be converted to a U-label 268 during preparation of a string for inclusion in a domainpart slot. 269 In addition, the string MUST be encoded as UTF-8 [RFC3629]. 271 3.2.2. Enforcement 273 An entity that performs enforcement in XMPP domainpart slots MUST 274 prepare a string as described in the previous section and MUST also 275 apply the normalization, case-mapping, and width-mapping rules 276 defined in [RFC5892]. 278 The order in which the rules are applied for IDNA2008 (see 279 [RFC5892] and [RFC5895]) is different from the order for 280 localparts and resourceparts as described under Section 3.3 and 281 Section 3.4. 283 3.2.3. Comparison 285 An entity that performs comparison of two strings before or after 286 their inclusion in XMPP domainpart slots MUST prepare each string and 287 enforce the normalization, case-mapping, and width-mapping rules 288 specified in the previous two sections. The two strings are to be 289 considered equivalent if they are an exact octet-for-octet match 290 (sometimes called "bit-string identity"). 292 3.3. Localpart 294 The localpart of a JID is an optional identifier placed before the 295 domainpart and separated from the latter by the '@' character. 296 Typically a localpart uniquely identifies the entity requesting and 297 using network access provided by a server (i.e., a local account), 298 although it can also represent other kinds of entities (e.g., a chat 299 room associated with a multi-user chat service [XEP-0045]). The 300 entity represented by an XMPP localpart is addressed within the 301 context of a specific domain (i.e., ). 303 The localpart of a JID MUST NOT be zero octets in length and MUST NOT 304 be more than 1023 octets in length. This rule is to be enforced 305 after any normalization and mapping of code points as well as 306 encoding of the string as UTF-8. 308 The localpart of a JID is an instance of the UsernameCaseMapped 309 profile of the PRECIS IdentifierClass, which is specified in 310 [I-D.ietf-precis-saslprepbis]. The rules and considerations provided 311 in that specification MUST be applied to XMPP localparts. 313 Implementation Note: XMPP uses the Simple Authentication and 314 Security Layer (SASL) [RFC4422] for authentication. At the time 315 of this writing, some SASL mechanisms use SASLprep [RFC4013] for 316 handling of usernames and passwords; in the future these SASL 317 mechanisms will likely transition to the use of PRECIS-based 318 handling rules as specified in [I-D.ietf-precis-saslprepbis]. 320 3.3.1. Further Excluded Characters 322 In XMPP, the following characters are explicitly disallowed in XMPP 323 localparts even though they are allowed by the IdentifierClass base 324 class and the UsernameCaseMapped profile: 326 U+0022 (QUOTATION MARK), i.e., " 328 U+0026 (AMPERSAND), i.e., & 330 U+0027 (APOSTROPHE), i.e., ' 331 U+002F (SOLIDUS), i.e., / 333 U+003A (COLON), i.e., : 335 U+003C (LESS-THAN SIGN), i.e., < 337 U+003E (GREATER-THAN SIGN), i.e., > 339 U+0040 (COMMERCIAL AT), i.e., @ 341 Implementation Note: An XMPP-specific method for escaping the 342 foregoing characters (along with U+0020, i.e., ASCII SPACE) has 343 been defined in the JID Escaping specification [XEP-0106]. 345 3.4. Resourcepart 347 The resourcepart of a JID is an optional identifier placed after the 348 domainpart and separated from the latter by the '/' character. A 349 resourcepart can modify either a address or a 350 mere address. Typically a resourcepart uniquely 351 identifies a specific connection (e.g., a device or location) or 352 object (e.g., an occupant in a multi-user chat room [XEP-0045]) 353 belonging to the entity associated with an XMPP localpart at a domain 354 (i.e., ). 356 XMPP entities SHOULD consider resourceparts to be opaque strings and 357 SHOULD NOT impute meaning to any given resourcepart. In particular: 359 o Use of the '/' character as a separator between the domainpart and 360 the resourcepart does not imply that XMPP addresses are 361 hierarchical in the way that, say, HTTP URIs are hierarchical (see 362 [RFC3986] for general discussion); thus for example an XMPP 363 address of the form does not 364 identify a resource "bar" that exists below a resource "foo" in a 365 hierarchy of resources associated with the entity 366 "localpart@domainpart". 368 o The '@' character is allowed in the resourcepart and is often used 369 in the "handle" shown in XMPP chatrooms [XEP-0045]. For example, 370 the JID describes an entity who 371 is an occupant of the room with a handle 372 of . However, chatroom services do not necessarily 373 check such an asserted handle against the occupant's real JID. 375 The resourcepart of a JID MUST NOT be zero octets in length and MUST 376 NOT be more than 1023 octets in length. This rule is to be enforced 377 after any normalization and mapping of code points as well as 378 encoding of the string as UTF-8. 380 The resourcepart of a JID is an instance of the OpaqueString profile 381 of the PRECIS FreeformClass, which is specified in 382 [I-D.ietf-precis-saslprepbis]. The rules and considerations provided 383 in that specification MUST be applied to XMPP resourceparts. 385 3.4.1. Applicability to XMPP 387 In some contexts, it might be appropriate to apply more restrictive 388 rules to the preparation, enforcement, and comparison of XMPP 389 resourceparts. For example, in XMPP Multi-User Chat [XEP-0045] it 390 might be appropriate to apply the rules specified in 391 [I-D.ietf-precis-nickname]. However, the application of more 392 restrictive rules is out of scope for resourceparts in general and is 393 properly defined in specifications for the relevant XMPP extensions. 395 3.5. Examples 397 The following examples illustrate a small number of JIDs that are 398 consistent with the format defined above. 400 Table 1: A sample of legal JIDs 402 +---------------------------------+---------------------------------+ 403 | # | JID | Notes | 404 +---------------------------------+---------------------------------+ 405 | 1 | juliet@example.com | A "bare JID" | 406 +---------------------------------+---------------------------------+ 407 | 2 | juliet@example.com/foo | A "full JID" | 408 +---------------------------------+---------------------------------+ 409 | 3 | juliet@example.com/foo bar | Single space in resourcepart | 410 +---------------------------------+---------------------------------+ 411 | 4 | foo\20bar@example.com | Single space in localpart, as | 412 | | | optionally escaped using the | 413 | | | XMPP "JID Escaping" extension | 414 +---------------------------------+---------------------------------+ 415 | 5 | fussball@example.com | Another bare JID | 416 +---------------------------------+---------------------------------+ 417 | 6 | fußball@example.com | The third character is LATIN | 418 | | | SMALL LETTER SHARP S (U+00DF) | 419 +---------------------------------+---------------------------------+ 420 | 7 | π@example.com | A localpart of GREEK SMALL | 421 | | | LETTER PI (U+03C0) | 422 +---------------------------------+---------------------------------+ 423 | 8 | π@example.com/Σ | A resourcepart of GREEK CAPITAL | 424 | | | LETTER SIGMA (U+03A3) | 425 +---------------------------------+---------------------------------+ 426 | 9 | π@example.com/σ | A resourcepart of GREEK SMALL | 427 | | | LETTER SIGMA (U+03C3) | 428 +---------------------------------+---------------------------------+ 429 | 10| π@example.com/ς | A resourcepart of GREEK SMALL | 430 | | | LETTER FINAL SIGMA (U+03C2) | 431 +---------------------------------+---------------------------------+ 432 | 11| henryiv@example.com/♚| A resourcepart of the Unicode | 433 | | | character BLACK CHESS KING | 434 | | | (U+265A) | 435 +---------------------------------+---------------------------------+ 436 | 12| example.com | A domainpart | 437 +---------------------------------+---------------------------------+ 438 | 13| example.com/foobar | A domainpart plus resourcepart | 439 +---------------------------------+---------------------------------+ 441 Several points are worth noting. Regarding examples 5 and 6: 442 although in German the character esszett (LATIN SMALL LETTER SHARP S, 443 U+00DF) can mostly be used interchangeably with the two characters 444 "ss", the localparts in these examples are different and (if desired) 445 a server would need to enforce a registration policy that disallows 446 one of them if the other is registered. Regarding examples 8, 9, and 447 10: case-mapping of GREEK CAPITAL LETTER SIGMA (U+03A3) to lowercase 448 (i.e., to GREEK SMALL LETTER SIGMA, U+03C3) during comparison would 449 result in matching the JIDs in examples 8 and 9; however, because the 450 PRECIS mapping rules do not account for the special status of GREEK 451 SMALL LETTER FINAL SIGMA (U+03C2), the JIDs in examples 8 and 10 or 452 examples 9 and 10 would not be matched. Regarding example 11: symbol 453 characters such as BLACK CHESS KING (U+265A) are allowed by the 454 PRECIS FreeformClass and thus can be used in resourceparts. 455 Regarding example 13: JIDs consisting of a domainpart and 456 resourcepart are rarely seen in the wild, but are allowed according 457 to the XMPP address format. 459 The following examples illustrate strings that are not JIDs because 460 they violate the format defined above. 462 Table 2: A sample of strings that violate the JID rules 464 +---------------------------------+---------------------------------+ 465 | # | Non-JID string | Notes | 466 +---------------------------------+---------------------------------+ 467 | 13| "juliet"@example.com | Quotation marks (U+0022) in | 468 | | | localpart | 469 +---------------------------------+---------------------------------+ 470 | 14| foo bar@example.com | Space (U+0020) in localpart | 471 +---------------------------------+---------------------------------+ 472 | 15| juliet@example.com/ foo | Leading space in resourcepart | 473 +---------------------------------+---------------------------------+ 474 | 16| <@example.com/> | Zero-length localpart and | 475 | | | resourcepart ('<' and '>') are | 476 | | | used here to show the start and | 477 | | | end of the JID in question | 478 +---------------------------------+---------------------------------+ 479 | 17| henryⅣ@example.com | The sixth character is ROMAN | 480 | | | NUMERAL FOUR (U+2163) | 481 +---------------------------------+---------------------------------+ 482 | 18| ♚@example.com | A localpart of BLACK CHESS KING | 483 | | | (U+265A) | 484 +---------------------------------+---------------------------------+ 485 | 19| juliet@ | A localpart without domainpart | 486 +---------------------------------+---------------------------------+ 487 | 20| /foobar | A resourcepart without | 488 | | domainpart | 489 +---------------------------------+---------------------------------+ 491 Here again, several points are worth noting. Regarding example 15, 492 even though ASCII SPACE (U+0020) is disallowed in the PRECIS 493 IdentifierClass, it can be escaped to "\20" in XMPP localparts by 494 using the JID Escaping rules defined in [XEP-0106], as illustrated by 495 example 4 in Table 1. Regarding example 17, the Unicode character 496 ROMAN NUMERAL FOUR (U+2163) has a compatibility equivalent of the 497 string formed of LATIN CAPITAL LETTER I (U+0049) and LATIN CAPITAL 498 LETTER V (U+0056), but characters with compatibility equivalents are 499 not allowed in the PRECIS IdentiferClass. Regarding example 18: 500 symbol characters such as BLACK CHESS KING (U+265A) are not allowed 501 in the PRECIS IdentifierClass; however, both of the non-ASCII 502 characters in examples 17 and 18 are allowed in the PRECIS Freeform 503 class and therefore in the XMPP resourcepart (as illustrated for 504 U+265A by example 11 in Table 1). Regarding examples 19 and 20: the 505 domainpart is required in a JID. 507 4. Enforcement in JIDs and JID Parts 509 Enforcement entails applying all of the rules specified in this 510 document. Enforcement of the XMPP address format rules is the 511 responsibility of XMPP servers. Although XMPP clients SHOULD prepare 512 complete JIDs and parts of JIDs in accordance with this document 513 before including them in protocol slots within XML streams, XMPP 514 servers MUST enforce the rules wherever possible and reject stanzas 515 and other XML elements that violate the rules (for stanzas, by 516 returning a error to the sender as described in 517 Section 8.3.3.8 of [RFC6120]). 519 Entities that enforce the rules specified in this document are 520 encouraged to be liberal in what they accept by following this 521 procedure: 523 1. Where possible, map characters (e.g, through width mapping, 524 additional mapping, special mapping, case mapping, or 525 normalization) and accept the mapped string. 527 2. If mapping is not possible (e.g., because a character is 528 disallowed in the FreeformClass), reject the string and return a 529 error. 531 Enforcement applies to complete JIDs and to parts of JIDs. To 532 facilitate implementation, this document defines the concepts of "JID 533 slot", "localpart slot", and "resourcepart slot" (similar to the 534 concept of a "domain name slot" for IDNA2008 defined in 535 Section 2.3.2.6 of [RFC5890]): 537 JID Slot: An XML element or attribute explicitly designated in XMPP 538 or in XMPP extensions for carrying a complete JID. 540 Localpart Slot: An XML element or attribute explicitly designated in 541 XMPP or in XMPP extensions for carrying the localpart of a JID. 543 Resourcepart Slot: An XML element or attribute explicitly designated 544 in XMPP or in XMPP extensions for carrying the resourcepart of a 545 JID. 547 A server is responsible for enforcing the address format rules when 548 receiving protocol elements from clients where the server is expected 549 to handle such elements directly or to use them for purposes of 550 routing a stanza to another domain or delivering a stanza to a local 551 entity; two examples from [RFC6120] are the 'to' attribute on XML 552 stanzas (which is a JID slot used by XMPP servers for routing of 553 outbound stanzas) and the child of the element 554 (which is a resourcepart slot used by XMPP servers for binding of a 555 resource to an account for routing of stanzas between the server and 556 a particular client). An example from [RFC6121] is the 'jid' 557 attribute of the roster element. 559 A server is not responsible for enforcing the rules when the protocol 560 elements are intended for communication among other entities, 561 typically within the payload of a stanza that the server is merely 562 routing to another domain or delivering to a local entity. Two 563 examples are the 'initiator' attribute in the Jingle extension 564 [XEP-0166] (which is a JID slot used for client-to-client 565 coordination of multimedia sessions) and the 'nick' attribute in the 566 Multi-User Chat extension [XEP-0045] (which is a resourcepart slot 567 used for administrative purposes in the context of XMPP chatrooms). 568 In such cases, clients SHOULD enforce the rules themselves and not 569 depend on the server to do so, and client implementers need to 570 understand that not enforcing the rules can lead to a degraded user 571 experience or to security vulnerabilities. However, when an add-on 572 service (e.g., a multi-user chat service) handles a stanza directly, 573 it ought to enforce the rules as well, as defined in the relevant 574 specification for that type of service. 576 This document does not provide an exhaustive list of JID slots, 577 localpart slots, or resourcepart slots. However, implementers of 578 core XMPP servers are advised to consider as JID slots at least the 579 following elements and attributes when they are handled directly or 580 used for purposes of routing to another domain or delivering to a 581 local entity: 583 o The 'from' and 'to' stream attributes and the 'from' and 'to' 584 stanza attributes [RFC6120]. 586 o The 'jid' attribute of the roster element for contact list 587 management [RFC6121]. 589 o The 'value' attribute of the element for Privacy Lists 590 [RFC3921] [XEP-0016] when the value of the 'type' attribute is 591 "jid". 593 o The 'jid' attribute of the element for Service Discovery 594 defined in [XEP-0030]. 596 o The element for Data Forms [XEP-0004], when the 'type' 597 attribute is "jid-single" or "jid-multi". 599 o The 'jid' attribute of the element for Bookmark 600 Storage [XEP-0048]. 602 o The of the element for vCard 3.0 [XEP-0054] 603 and the child of the element for vCard 4.0 604 [XEP-0292] when the XML character data identifies an XMPP URI 605 [RFC5122]. 607 o The 'from' attribute of the element for Delayed Delivery 608 [XEP-0203]. 610 o The 'jid' attribute of the element for the Blocking 611 Command [XEP-0191]. 613 o The 'from' and 'to' attributes of the and 614 elements for Server Dialback [RFC3921], [XEP-0220]. 616 o The 'from' and 'to' attributes of the , , and 617 elements for the Jabber Component Protocol [XEP-0114]. 619 Developers of XMPP clients and specialized XMPP add-on services are 620 advised to check the appropriate specifications for JID slots, 621 localpart slots, and resourcepart slots in XMPP protocol extensions 622 such as Service Discovery [XEP-0030], Multi-User Chat [XEP-0045], 623 Publish-Subscribe [XEP-0060], SOCKS5 Bytestreams [XEP-0065], In-Band 624 Registration [XEP-0077], Roster Item Exchange [XEP-0144], and Jingle 625 [XEP-0166]. 627 5. Internationalization Considerations 629 XMPP applications MUST support IDNA2008 for domainparts as described 630 under Section 3.2, the "UsernameCaseMapped" profile for localparts as 631 described under Section 3.3, and the "OpaqueString" profile for 632 resourceparts as described under Section 3.4. This enables XMPP 633 addresses to include a wide variety of characters outside the ASCII 634 range. Rules for enforcement of the XMPP address format are provided 635 in [RFC6120] and specifications for various XMPP extensions. 637 Interoperability Note: For backward compatibility, many existing 638 XMPP implementations and deployments support IDNA2003 [RFC3490] 639 for domainparts, and the stringprep [RFC3454] profiles Nodeprep 640 and Resourceprep [RFC3920] for localparts and resourceparts. 642 6. IANA Considerations 644 6.1. Stringprep Profiles Registry 646 The Stringprep specification [RFC3454] did not provide for entries in 647 the Stringprep Profiles registry to be marked as anything except 648 current or not current. Because this document obsoletes RFC 6122, 649 which registered the "Nodeprep" and "Resourceprep" profiles, IANA is 650 requested at the least to mark those profiles as not current 651 (preferably with a pointer to this document). 653 7. Security Considerations 655 7.1. Reuse of PRECIS 657 The security considerations described in [I-D.ietf-precis-framework] 658 apply to the "IdentifierClass" and "FreeformClass" base string 659 classes used in this document for XMPP localparts and resourceparts, 660 respectively. The security considerations described in [RFC5890] 661 apply to internationalized domain names, which are used here for XMPP 662 domainparts. 664 7.2. Reuse of Unicode 666 The security considerations described in [UTS39] apply to the use of 667 Unicode characters in XMPP addresses. 669 7.3. Address Spoofing 671 There are two forms of address spoofing: forging and mimicking. 673 7.3.1. Address Forging 675 In the context of XMPP technologies, address forging occurs when an 676 entity is able to generate an XML stanza whose 'from' address does 677 not correspond to the account credentials with which the entity 678 authenticated onto the network (or an authorization identity provided 679 during negotiation of SASL authentication [RFC4422] as described in 680 [RFC6120]). For example, address forging occurs if an entity that 681 authenticated as "juliet@im.example.com" is able to send XML stanzas 682 from "nurse@im.example.com" or "romeo@example.net". 684 Address forging is difficult in XMPP systems, given the requirement 685 for sending servers to stamp 'from' addresses and for receiving 686 servers to verify sending domains via server-to-server authentication 687 (see [RFC6120]). However, address forging is possible if: 689 o A poorly implemented server ignores the requirement for stamping 690 the 'from' address. This would enable any entity that 691 authenticated with the server to send stanzas from any 692 localpart@domainpart as long as the domainpart matches the sending 693 domain of the server. 695 o An actively malicious server generates stanzas on behalf of any 696 registered account at the domain or domains hosted at that server. 698 Therefore, an entity outside the security perimeter of a particular 699 server cannot reliably distinguish between JIDs of the form 700 at that server and thus can authenticate only 701 the domainpart of such JIDs with any level of assurance. This 702 specification does not define methods for discovering or 703 counteracting the kind of poorly implemented or rogue servers just 704 described. However, the end-to-end authentication or signing of XMPP 705 stanzas could help to mitigate this risk, since it would require the 706 rogue server to generate false credentials for signing or encryption 707 of each stanza, in addition to modifying 'from' addresses. 709 7.3.2. Address Mimicking 711 Address mimicking occurs when an entity provides legitimate 712 authentication credentials for and sends XML stanzas from an account 713 whose JID appears to a human user to be the same as another JID. 714 Because many characters are visually similar, it is relatively easy 715 to mimic JIDs in XMPP systems. As one simple example, the localpart 716 "ju1iet" (using the Arabic numeral one as the third character) might 717 appear the same as the localpart "juliet" (using lowercase "L" as the 718 third character). 720 As explained in [RFC5890], [I-D.ietf-precis-framework], [UTR36], and 721 [UTS39], there is no straightforward solution to the problem of 722 visually similar characters. Furthermore, IDNA and PRECIS 723 technologies do not attempt to define such a solution. As a result, 724 XMPP domainparts, localparts, and resourceparts could contain such 725 characters, leading to security vulnerabilities such as the 726 following: 728 o A domainpart is always employed as one part of an entity's address 729 in XMPP. One common usage is as the address of a server or 730 server-side service, such as a multi-user chat service [XEP-0045]. 731 The security of such services could be compromised based on 732 different interpretations of the internationalized domainpart; for 733 example, a user might authorize a malicious entity at a fake 734 server to view the user's presence information, or a user could 735 join chatrooms at a fake multi-user chat service. 737 o A localpart can be employed as one part of an entity's address in 738 XMPP. One common usage is as the username of an instant messaging 739 user; another is as the name of a multi-user chat room; and many 740 other kinds of entities could use localparts as part of their 741 addresses. The security of such services could be compromised 742 based on different interpretations of the internationalized 743 localpart; for example, a user entering a single internationalized 744 localpart could access another user's account information, or a 745 user could gain access to a hidden or otherwise restricted chat 746 room or service. 748 o A resourcepart can be employed as one part of an entity's address 749 in XMPP. One common usage is as the name for an instant messaging 750 user's connected resource; another is as the nickname of a user in 751 a multi-user chat room; and many other kinds of entities could use 752 resourceparts as part of their addresses. The security of such 753 services could be compromised based on different interpretations 754 of the internationalized resourcepart; for example, two or more 755 confusable resources could be bound at the same time to the same 756 account (resulting in inconsistent authorization decisions in an 757 XMPP application that uses full JIDs), or a user could send a 758 private message to someone other than the intended recipient in a 759 multi-user chat room. 761 XMPP services and clients are strongly encouraged to define and 762 implement consistent policies regarding the registration, storage, 763 and presentation of visually similar characters in XMPP systems. In 764 particular, service providers and software implementers are strongly 765 encouraged to apply the policies recommended in 766 [I-D.ietf-precis-framework]. 768 8. Conformance Requirements 770 This section describes a protocol feature set that summarizes the 771 conformance requirements of this specification (similar feature sets 772 are provided for XMPP in [RFC6120] and [RFC6121]). This feature set 773 is appropriate for use in software certification, interoperability 774 testing, and implementation reports. For each feature, this section 775 provides the following information: 777 o A human-readable name 779 o An informational description 780 o A reference to the particular section of this document that 781 normatively defines the feature 783 o Whether the feature applies to the Client role, the Server role, 784 or both (where "N/A" signifies that the feature is not applicable 785 to the specified role) 787 o Whether the feature MUST or SHOULD be implemented, where the 788 capitalized terms are to be understood as described in [RFC2119] 790 The feature set specified here provides a basis for interoperability 791 testing and follows the spirit of a proposal made by Larry Masinter 792 within the IETF's NEWTRK Working Group in 2005 [INTEROP]. 794 Feature: address-domain-length 796 Description: Ensure that the domainpart of an XMPP address is at 797 least one octet in length and at most 1023 octets in length, and 798 that it conforms to the underlying length limits of the DNS. 800 Section: Section 3.2 802 Roles: Server MUST, client SHOULD. 804 Feature: address-domain-prep 806 Description: Ensure that the domainpart of an XMPP address conforms 807 to IDNA2008, that it contains only NR-LDH labels and U-labels (not 808 A-labels), and that all uppercase and titlecase code points are 809 mapped to their lowercase equivalents. 811 Section: Section 3.2 813 Roles: Server MUST, client SHOULD. 815 Feature: address-localpart-length 817 Description: Ensure that the localpart of an XMPP address is at 818 least one octet in length and at most 1023 octets in length. 820 Section: Section 3.3 822 Roles: Server MUST, client SHOULD. 824 Feature: address-localpart-prep 826 Description: Ensure that the localpart of an XMPP address conforms 827 to the "UsernameCaseMapped" profile of the PRECIS IdentifierClass. 829 Section: Section 3.3 831 Roles: Server MUST, client SHOULD. 833 Feature: address-resource-length 835 Description: Ensure that the resourcepart of an XMPP address is at 836 least one octet in length and at most 1023 octets in length. 838 Section: Section 3.4 840 Roles: Server MUST, client SHOULD. 842 Feature: address-resource-prep 844 Description: Ensure that the resourcepart of an XMPP address 845 conforms to the "OpaqueString" profile of the PRECIS 846 FreeformClass. 848 Section: Section 3.4 850 Roles: Server MUST, client SHOULD. 852 9. References 854 9.1. Normative References 856 [I-D.ietf-precis-framework] 857 Saint-Andre, P. and M. Blanchet, "Precis Framework: 858 Handling Internationalized Strings in Protocols", draft- 859 ietf-precis-framework-20 (work in progress), November 860 2014. 862 [I-D.ietf-precis-saslprepbis] 863 Saint-Andre, P. and A. Melnikov, "Username and Password 864 Preparation Algorithms", draft-ietf-precis-saslprepbis-11 865 (work in progress), November 2014. 867 [RFC1034] Mockapetris, P., "Domain names - concepts and facilities", 868 STD 13, RFC 1034, November 1987. 870 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 871 Requirement Levels", BCP 14, RFC 2119, March 1997. 873 [RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO 874 10646", STD 63, RFC 3629, November 2003. 876 [RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax 877 Specifications: ABNF", STD 68, RFC 5234, January 2008. 879 [RFC5890] Klensin, J., "Internationalized Domain Names for 880 Applications (IDNA): Definitions and Document Framework", 881 RFC 5890, August 2010. 883 [RFC5891] Klensin, J., "Internationalized Domain Names in 884 Applications (IDNA): Protocol", RFC 5891, August 2010. 886 [RFC5892] Faltstrom, P., "The Unicode Code Points and 887 Internationalized Domain Names for Applications (IDNA)", 888 RFC 5892, August 2010. 890 [RFC6120] Saint-Andre, P., "Extensible Messaging and Presence 891 Protocol (XMPP): Core", RFC 6120, March 2011. 893 [UNICODE] The Unicode Consortium, "The Unicode Standard, Version 894 6.3", 2013, 895 . 897 [UTR36] The Unicode Consortium, "Unicode Technical Report #36: 898 Unicode Security Considerations", November 2013, 899 . 901 9.2. Informative References 903 [I-D.ietf-precis-nickname] 904 Saint-Andre, P., "Preparation and Comparison of 905 Nicknames", draft-ietf-precis-nickname-13 (work in 906 progress), November 2014. 908 [INTEROP] Masinter, L., "Formalizing IETF Interoperability 909 Reporting", Work in Progress, October 2005. 911 [RFC1123] Braden, R., "Requirements for Internet Hosts - Application 912 and Support", STD 3, RFC 1123, October 1989. 914 [RFC1535] Gavron, E., "A Security Problem and Proposed Correction 915 With Widely Deployed DNS Software", RFC 1535, October 916 1993. 918 [RFC3454] Hoffman, P. and M. Blanchet, "Preparation of 919 Internationalized Strings ("stringprep")", RFC 3454, 920 December 2002. 922 [RFC3490] Faltstrom, P., Hoffman, P., and A. Costello, 923 "Internationalizing Domain Names in Applications (IDNA)", 924 RFC 3490, March 2003. 926 See Section 1 for an explanation of why the normative 927 reference to an obsoleted specification is needed. 929 [RFC3920] Saint-Andre, P., Ed., "Extensible Messaging and Presence 930 Protocol (XMPP): Core", RFC 3920, October 2004. 932 [RFC3921] Saint-Andre, P., Ed., "Extensible Messaging and Presence 933 Protocol (XMPP): Instant Messaging and Presence", RFC 934 3921, October 2004. 936 [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform 937 Resource Identifier (URI): Generic Syntax", STD 66, RFC 938 3986, January 2005. 940 [RFC3987] Duerst, M. and M. Suignard, "Internationalized Resource 941 Identifiers (IRIs)", RFC 3987, January 2005. 943 [RFC4013] Zeilenga, K., "SASLprep: Stringprep Profile for User Names 944 and Passwords", RFC 4013, February 2005. 946 [RFC4422] Melnikov, A. and K. Zeilenga, "Simple Authentication and 947 Security Layer (SASL)", RFC 4422, June 2006. 949 [RFC5122] Saint-Andre, P., "Internationalized Resource Identifiers 950 (IRIs) and Uniform Resource Identifiers (URIs) for the 951 Extensible Messaging and Presence Protocol (XMPP)", RFC 952 5122, February 2008. 954 [RFC5894] Klensin, J., "Internationalized Domain Names for 955 Applications (IDNA): Background, Explanation, and 956 Rationale", RFC 5894, August 2010. 958 [RFC5895] Resnick, P. and P. Hoffman, "Mapping Characters for 959 Internationalized Domain Names in Applications (IDNA) 960 2008", RFC 5895, September 2010. 962 [RFC6121] Saint-Andre, P., "Extensible Messaging and Presence 963 Protocol (XMPP): Instant Messaging and Presence", RFC 964 6121, March 2011. 966 [RFC6122] Saint-Andre, P., "Extensible Messaging and Presence 967 Protocol (XMPP): Address Format", RFC 6122, March 2011. 969 [RFC6365] Hoffman, P. and J. Klensin, "Terminology Used in 970 Internationalization in the IETF", BCP 166, RFC 6365, 971 September 2011. 973 [RFC6885] Blanchet, M. and A. Sullivan, "Stringprep Revision and 974 Problem Statement for the Preparation and Comparison of 975 Internationalized Strings (PRECIS)", RFC 6885, March 2013. 977 [UTS39] The Unicode Consortium, "Unicode Technical Standard #39: 978 Unicode Security Mechanisms", July 2012, 979 . 981 [XEP-0004] 982 Eatmon, R., Hildebrand, J., Miller, J., Muldowney, T., and 983 P. Saint-Andre, "Data Forms", XSF XEP 0004, August 2007. 985 [XEP-0016] 986 Millard, P. and P. Saint-Andre, "Privacy Lists", XSF XEP 987 0016, February 2007. 989 [XEP-0029] 990 Kaes, C., "Definition of Jabber Identifiers (JIDs)", XSF 991 XEP 0029, October 2003. 993 [XEP-0030] 994 Hildebrand, J., Millard, P., Eatmon, R., and P. Saint- 995 Andre, "Service Discovery", XSF XEP 0030, June 2008. 997 [XEP-0045] 998 Saint-Andre, P., "Multi-User Chat", XSF XEP 0045, February 999 2012. 1001 [XEP-0048] 1002 Blackman, R., Millard, P., and P. Saint-Andre, 1003 "Bookmarks", XSF XEP 0048, November 2007. 1005 [XEP-0054] 1006 Saint-Andre, P., "vcard-temp", XSF XEP 0054, July 2008. 1008 [XEP-0060] 1009 Millard, P., Saint-Andre, P., and R. Meijer, "Publish- 1010 Subscribe", XSF XEP 0060, July 2010. 1012 [XEP-0065] 1013 Smith, D., Miller, M., Saint-Andre, P., and J. Karneges, 1014 "SOCKS5 Bytestreams", XSF XEP 0065, April 2011. 1016 [XEP-0077] 1017 Saint-Andre, P., "In-Band Registration", XSF XEP 0077, 1018 January 2012. 1020 [XEP-0106] 1021 Hildebrand, J. and P. Saint-Andre, "JID Escaping", XSF XEP 1022 0106, June 2007. 1024 [XEP-0114] 1025 Saint-Andre, P., "Jabber Component Protocol", XSF XEP 1026 0114, March 2005. 1028 [XEP-0144] 1029 Saint-Andre, P., "Roster Item Exchange", XSF XEP 0144, 1030 August 2005. 1032 [XEP-0165] 1033 Saint-Andre, P., "Best Practices to Discourage JID 1034 Mimicking", XSF XEP 0165, December 2007. 1036 [XEP-0166] 1037 Ludwig, S., Beda, J., Saint-Andre, P., McQueen, R., Egan, 1038 S., and J. Hildebrand, "Jingle", XSF XEP 0166, December 1039 2009. 1041 [XEP-0191] 1042 Saint-Andre, P., "Blocking Command", XSF XEP 0191, July 1043 2012. 1045 [XEP-0203] 1046 Saint-Andre, P., "Delayed Delivery", XSF XEP 0203, 1047 September 2009. 1049 [XEP-0220] 1050 Miller, J., Saint-Andre, P., and P. Hancke, "Server 1051 Dialback", XSF XEP 0220, August 2012. 1053 [XEP-0292] 1054 Saint-Andre, P. and S. Mizzi, "vCard4 Over XMPP", XSF XEP 1055 0292, October 2011. 1057 [XML] Maler, E., Yergeau, F., Sperberg-McQueen, C., Paoli, J., 1058 and T. Bray, "Extensible Markup Language (XML) 1.0 (Fifth 1059 Edition)", World Wide Web Consortium Recommendation REC- 1060 xml-20081126, November 2008, 1061 . 1063 Appendix A. Differences from RFC 6122 1065 Based on consensus derived from working group discussion, 1066 implementation and deployment experience, and formal interoperability 1067 testing, the following substantive modifications were made from RFC 1068 6122. 1070 o Changed domainpart preparation to use IDNA2008 (instead of 1071 IDNA2003). 1073 o Changed localpart preparation to use the UsernameCaseMapped 1074 profile of the PRECIS IdentifierClass (instead of the Nodeprep 1075 profile of Stringprep). 1077 o Changed resourcepart preparation to use the OpaqueString profile 1078 of the PRECIS FreeformClass (instead of the Resourceprep profile 1079 of Stringprep). 1081 o Specified that internationalized labels within domainparts must be 1082 U-labels (instead of "should be" U-labels). 1084 o Specified that fullwidth and halfwidth characters must be mapped 1085 to their decomposition mappings (previously handled through the 1086 use of NFKC). 1088 o Specified the use of Unicode Normalization Form C (instead of 1089 Unicode Normalization Form KC as specified in the Nodeprep and 1090 Resourceprep profiles of Stringprep). 1092 o Specified that servers must enforce the address formatting rules. 1094 Appendix B. Acknowledgements 1096 Thanks to Miguel Garcia, Joe Hildebrand, Jonathan Lennox, Matt 1097 Miller, and Florian Zeitz for their feedback. 1099 Some text in this document was borrowed or adapted from [RFC5890], 1100 [RFC5891], [RFC5894], and [XEP-0165]. 1102 Peter Saint-Andre wishes to acknowledge Cisco Systems, Inc., for 1103 employing him during his work on earlier versions of this document. 1105 Author's Address 1106 Peter Saint-Andre 1107 &yet 1109 Email: peter@andyet.com 1110 URI: https://andyet.com/