RFC 3080

The Blocks Extensible Exchange Protocol Core

πŸ“… published March 2001, from ietf

RFC 3080: The Blocks Extensible Exchange Protocol Core ✨

Okay bestie, this is RFC 3080, and it's giving main character energy πŸ‘‘ It's the core of BEEP, a protocol that lets lots of conversations happen at the same time over one connection. Let's get into it πŸ’…

Here's the title block, all in one place:

  • RFC number: 3080
  • Title: The Blocks Extensible Exchange Protocol Core
  • Author: M. Rose, Invisible Worlds, Inc.
  • Category: Standards Track
  • Date: March 2001
  • Stream: Network Working Group
  • Obsoletes / Updates: this title block doesn't list either one πŸ™ˆ

Status of this Memo πŸ“œ

This document specifies an Internet standards track protocol for the Internet community, and it wants feedback and suggestions for improvements 🫢 For the current standardization state and status of this protocol, check the current edition of the "Internet Official Protocol Standards" (STD 1). Distribution of this memo is unlimited 🌈

Copyright (C) The Internet Society (2001). All Rights Reserved.

Abstract πŸ¦‹

This memo describes a generic application protocol kernel for connection-oriented, asynchronous interactions called the BEEP (Blocks Extensible Exchange Protocol) core. BEEP permits simultaneous and independent exchanges within the context of a single application user-identity, and it supports both textual and binary messages ✨

Table of Contents πŸ—‚οΈ

   1.      Introduction . . . . . . . . . . . . . . . . . . . . . . .  4
   2.      The BEEP Core  . . . . . . . . . . . . . . . . . . . . . .  5
   2.1     Roles  . . . . . . . . . . . . . . . . . . . . . . . . . .  6
   2.1.1   Exchange Styles  . . . . . . . . . . . . . . . . . . . . .  6
   2.2     Messages and Frames  . . . . . . . . . . . . . . . . . . .  7
   2.2.1   Frame Syntax . . . . . . . . . . . . . . . . . . . . . . .  8
   2.2.1.1 Frame Header . . . . . . . . . . . . . . . . . . . . . . .  9
   2.2.1.2 Frame Payload  . . . . . . . . . . . . . . . . . . . . . . 12
   2.2.1.3 Frame Trailer  . . . . . . . . . . . . . . . . . . . . . . 13
   2.2.2   Frame Semantics  . . . . . . . . . . . . . . . . . . . . . 14
   2.2.2.1 Poorly-formed Messages . . . . . . . . . . . . . . . . . . 14
   2.3     Channel Management . . . . . . . . . . . . . . . . . . . . 15
   2.3.1   Message Semantics  . . . . . . . . . . . . . . . . . . . . 16
   2.3.1.1 The Greeting Message . . . . . . . . . . . . . . . . . . . 16
   2.3.1.2 The Start Message  . . . . . . . . . . . . . . . . . . . . 17
   2.3.1.3 The Close Message  . . . . . . . . . . . . . . . . . . . . 20
   2.3.1.4 The OK Message . . . . . . . . . . . . . . . . . . . . . . 23
   2.3.1.5 The Error Message  . . . . . . . . . . . . . . . . . . . . 23
   2.4     Session Establishment and Release  . . . . . . . . . . . . 25
   2.5     Transport Mappings . . . . . . . . . . . . . . . . . . . . 27
   2.5.1   Session Management . . . . . . . . . . . . . . . . . . . . 27
   2.5.2   Message Exchange . . . . . . . . . . . . . . . . . . . . . 27
   2.6     Asynchrony . . . . . . . . . . . . . . . . . . . . . . . . 28
   2.6.1   Within a Single Channel  . . . . . . . . . . . . . . . . . 28
   2.6.2   Between Different Channels . . . . . . . . . . . . . . . . 28
   2.6.3   Pre-emptive Replies  . . . . . . . . . . . . . . . . . . . 29
   2.6.4   Interference . . . . . . . . . . . . . . . . . . . . . . . 29
   2.7     Peer-to-Peer Behavior  . . . . . . . . . . . . . . . . . . 30
   3.      Transport Security . . . . . . . . . . . . . . . . . . . . 31
   3.1     The TLS Transport Security Profile . . . . . . . . . . . . 34
   3.1.1   Profile Identification and Initialization  . . . . . . . . 34
   3.1.2   Message Syntax . . . . . . . . . . . . . . . . . . . . . . 35
   3.1.3   Message Semantics  . . . . . . . . . . . . . . . . . . . . 36
   3.1.3.1 The Ready Message  . . . . . . . . . . . . . . . . . . . . 36
   3.1.3.2 The Proceed Message  . . . . . . . . . . . . . . . . . . . 36
   4.      User Authentication  . . . . . . . . . . . . . . . . . . . 37
   4.1     The SASL Family of Profiles  . . . . . . . . . . . . . . . 38
   4.1.1   Profile Identification and Initialization  . . . . . . . . 39
   4.1.2   Message Syntax . . . . . . . . . . . . . . . . . . . . . . 42
   4.1.3   Message Semantics  . . . . . . . . . . . . . . . . . . . . 43
   5.      Registration Templates . . . . . . . . . . . . . . . . . . 44
   5.1     Profile Registration Template  . . . . . . . . . . . . . . 44
   5.2     Feature Registration Template  . . . . . . . . . . . . . . 44
   6.      Initial Registrations  . . . . . . . . . . . . . . . . . . 45
   6.1     Registration: BEEP Channel Management  . . . . . . . . . . 45
   6.2     Registration: TLS Transport Security Profile . . . . . . . 45
   6.3     Registration: SASL Family of Profiles  . . . . . . . . . . 46
   6.4     Registration: application/beep+xml . . . . . . . . . . . . 47
   7.      DTDs . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
   7.1     BEEP Channel Management DTD  . . . . . . . . . . . . . . . 48
   7.2     TLS Transport Security Profile DTD . . . . . . . . . . . . 50
   7.3     SASL Family of Profiles DTD  . . . . . . . . . . . . . . . 51
   8.      Reply Codes  . . . . . . . . . . . . . . . . . . . . . . . 52
   9.      Security Considerations  . . . . . . . . . . . . . . . . . 53
           References . . . . . . . . . . . . . . . . . . . . . . . . 54
           Author's Address . . . . . . . . . . . . . . . . . . . . . 55
   A.      Acknowledgements . . . . . . . . . . . . . . . . . . . . . 56
   B.      IANA Considerations  . . . . . . . . . . . . . . . . . . . 57
           Full Copyright Statement . . . . . . . . . . . . . . . . . 58

1. Introduction ✨

This memo describes a generic application protocol kernel for connection-oriented, asynchronous interactions called BEEP πŸ’–

At BEEP's core is a framing mechanism that lets peers have simultaneous and independent exchanges of messages. Messages are arbitrary MIME [1] content, but they're usually textual (structured using XML [2]) 🧚

All exchanges happen inside a channel, which is a binding to a well-defined aspect of the application, like transport security, user authentication, or data exchange 🌸

Each channel has an associated "profile" that defines the syntax and semantics of the messages exchanged. Channel management is implicit in how BEEP works. On top of defining BEEP's channel management profile, this document also defines:

  • the TLS [3] transport security profile; and,
  • the SASL [4] family of profiles.

Other profiles, like the ones used for data exchange, are defined by an application protocol designer πŸ’…

2. The BEEP Core 🌈

A BEEP session gets mapped onto an underlying transport service. A separate series of documents describes how a particular transport service realizes a BEEP session. For example, [5] describes how a BEEP session is mapped onto a single TCP [6] connection πŸ¦‹

When a session is established, each BEEP peer advertises the profiles it supports. Later on, when a channel is created, the client supplies one or more proposed profiles for that channel. If the server creates the channel, it picks one of the profiles and sends it back in a reply. Otherwise, it may indicate that none of the profiles are acceptable, and decline creating the channel πŸ™…β€β™€οΈ

Channel usage falls into one of two categories:

  • initial tuning: these are used by profiles that perform initialization once the BEEP session is established (e.g., negotiating the use of transport security). Although several exchanges may be required to perform the initialization, these channels become inactive early in the BEEP session and stay that way for the duration.
  • continuous: these are used by profiles that support data exchange. Typically, these channels are created after the initial tuning channels have gone quiet.

Note that because of their special nature, only one tuning channel may be established at any given time. BEEP, on the other hand, allows multiple data exchange channels to be in use at once πŸŽ€

2.1 Roles 🎭

Although BEEP is peer-to-peer, it's handy to label each peer by the role it's playing at a given time:

  • When a BEEP session is established, the peer that waits for new connections is acting in the listening role. The other peer, which connects to the listener, is acting in the initiating role. In the examples that follow, these are referred to as "L:" and "I:", respectively.
  • A BEEP peer that starts an exchange is termed the client. The other BEEP peer is termed the server. In the examples that follow, these are referred to as "C:" and "S:", respectively.

Typically, a BEEP peer acting in the server role is also acting in a listening role. However, because BEEP is peer-to-peer in nature, no such requirement exists πŸ’œ

2.1.1 Exchange Styles πŸ“

BEEP allows three styles of exchange:

  • MSG/RPY: the client sends a "MSG" message asking the server to perform some task. The server performs the task and replies with a "RPY" message (termed a positive reply).
  • MSG/ERR: the client sends a "MSG" message. The server does not perform any task and replies with an "ERR" message (termed a negative reply).
  • MSG/ANS: the client sends a "MSG" message. The server, while performing some task, replies with zero or more "ANS" messages. When the task is complete, it sends a "NUL" message, which signifies the end of the reply.

The first two styles are termed one-to-one exchanges, whilst the third style is termed a one-to-many exchange πŸ”₯

2.2 Messages and Frames πŸ“¦

A message is structured according to the rules of MIME. Accordingly, each message may begin with "entity-headers" (c.f., MIME's Section 3 [1]). If none, or only some, of the "entity-headers" are present:

  • the default "Content-Type" is "application/octet-stream"; and,
  • the default "Content-Transfer-Encoding" is "binary".

Normally, a message is sent in a single frame. However, it may be convenient or necessary to split a message into multiple frames (e.g., if only part of a message is ready to be sent) ⭐

Each frame consists of a header, the payload, and a trailer. The header and trailer are each represented using printable ASCII characters and are terminated with a CRLF pair. Between the header and the trailer is the payload, which consists of zero or more octets 🫢

For example, here is a message contained in a single frame with a payload of 120 octets spread over 5 lines (each line is terminated with a CRLF pair):

    C: MSG 0 1 . 52 120
    C: Content-Type: application/beep+xml
    C:
    C: <start number='1'>
    C:    <profile uri='http://iana.org/beep/SASL/OTP' />
    C: </start>
    C: END

Notice that the entire message is represented in a single frame πŸ§šβ€β™€οΈ

2.2.1 Frame Syntax 🧩

The ABNF [7] for a frame is:

frame      = data / mapping

data       = header payload trailer

header     = msg / rpy / err / ans / nul

msg        = "MSG" SP common          CR LF
rpy        = "RPY" SP common          CR LF
ans        = "ANS" SP common SP ansno CR LF
err        = "ERR" SP common          CR LF
nul        = "NUL" SP common          CR LF

common     = channel SP msgno SP more SP seqno SP size
channel    = 0..2147483647
msgno      = 0..2147483647
more       = "." / "*"
seqno      = 0..4294967295
size       = 0..2147483647
ansno      = 0..2147483647

payload    = *OCTET

trailer    = "END" CR LF

mapping    = ;; each transport mapping may define additional frames

That's the first chunk, bestie! 🌈 More of the frame rules, the message semantics, and the rest of the spec are coming up in part 2 πŸ¦‹

2.2.1.1 Frame Header ✨

okay so the frame header is a three-character keyword (it has to be one of MSG, RPY, ERR, ANS, or NUL) followed by zero or more parameters πŸŽ€. Every component is separated by a single space (decimal code 32, " "), and the header ends with a CRLF pair πŸ’….

The channel number (channel) MUST be a non-negative integer, in the range 0..2147483647 πŸ¦‹

The message number (msgno) MUST be a non-negative integer in the range 0..2147483647, AND it MUST have a different value than all other MSG messages on the same channel that haven't been completely replied to yet 🌸

The continuation indicator (more) is either decimal code 42, *, or decimal code 46, .. It tells you whether this is the final frame of the message πŸ’œ

  • intermediate (*): at least one other frame follows for the message; or,
  • complete (.): this frame completes the message.

The sequence number (seqno) MUST be a non-negative integer in the range 0..4294967295. It gives the sequence number of the first octet in the payload, for the associated channel (c.f., Section 2.2.1.2) 🌈

The payload size (size) MUST be a non-negative integer in the range 0..2147483647, and it tells you the exact number of octets in the payload. (This does NOT include the header or the trailer πŸ™ˆ)

Note that a frame MAY have an empty payload, like this 🧚

    S: RPY 0 1 * 287 20
    S:     ...
    S:     ...
    S: END
    S: RPY 0 1 . 307 0
    S: END

The answer number (ansno) MUST be a non-negative integer in the range 0..4294967295, and it MUST have a different value than all other answers in progress for the message being replied to πŸ‘‘

There are two kinds of frames: data and mapping πŸ“ Each transport mapping (c.f., Section 2.5) MAY define its own frames. For example, [5] defines the SEQ frame. The rest of this section is all about data frames.

When a message gets segmented and sent as several frames, those frames MUST be sent sequentially, with no frames from other messages on the same channel sneaking in between them 🚫 BUT there are two exceptions, bestie. First, there's no restriction on interleaving frames for other channels. Second, in a one-to-many exchange, multiple answers MAY be in progress at the same time. So frames for ANS messages MAY be interleaved on the same channel, and the answer number is what lets the receiver collate them 🧩

    S: ANS 1 0 * 0 20 0
    S:     ...
    S:     ...
    S: END
    S: ANS 1 0 * 20 20 1
    S:     ...
    S:     ...
    S: END
    S: ANS 1 0 . 40 10 0
    S:     ...
    S: END

This shows two ANS messages interleaved on channel 1 as part of a reply to message number 0 ✨ Also, the sequence number goes up for every frame sent on the channel, and it's totally independent of which messages are inside those frames. Iconic, honestly πŸ’–

Okay, now the rules for spotting poorly-formed frames. These are the ones you NEED to catch 😭

  • if the header doesn't start with MSG, RPY, ERR, ANS, or NUL;
  • if any of the parameters in the header can't be determined or are invalid (i.e., syntactically incorrect);
  • if the value of the channel number doesn't refer to an existing channel;
  • if the header starts with MSG, and the message number refers to a MSG message that has been completely received but for which a reply has NOT been completely sent;
  • if the header doesn't start with MSG, and refers to a message number for which a reply has already been completely received;
  • if the header doesn't start with MSG, and refers to a message number that has never been sent (except during session establishment, c.f., Section 2.3.1.1);
  • if the header starts with MSG, RPY, ERR, or ANS, and refers to a message number for which at least one other frame has been received, and the three-character keyword starting this frame and the immediately-previous received frame for this message number are not identical;
  • if the header starts with NUL, and refers to a message number for which at least one other frame has been received, and the keyword of the immediately-previous received frame for this reply isn't ANS;
  • if the continuation indicator of the previous frame received on the same channel was intermediate (*), and its message number isn't identical to this frame's message number;
  • if the value of the sequence number doesn't correspond to the expected value for the associated channel (c.f., Section 2.2.1.2); or,
  • if the header starts with NUL, and the continuation indicator is intermediate (*) or the payload size is non-zero.

If a frame is poorly-formed, the session gets terminated without any response being generated, and it is RECOMMENDED that a diagnostic entry be logged πŸ₯Ί

2.2.1.2 Frame Payload 🌸

The frame payload is zero or more octets, babe πŸ“

Every payload octet sent in each direction on a channel has an associated sequence number. Payload octets are numbered within a frame so that the first payload octet is the lowest numbered, and the rest follow consecutively. (When a channel gets created, the sequence number for the first payload octet of the first frame is 0 πŸ¦‹)

The sequence number space is finite, though VERY large, ranging from 0..4294967295 (2**32 - 1). Because it's finite, all arithmetic on sequence numbers is done modulo 2**32. This unsigned arithmetic keeps the relationships between sequence numbers intact as they wrap from 2**32 - 1 back around to 0 πŸ”„ If you want the arithmetic properties explained properly, check out Sections 2 through 5 of [8].

When you receive a frame, the sum of its sequence number and payload size, modulo 4294967296 (2**32), gives you the expected sequence number for the first payload octet of the next frame. So if a frame arrives and its sequence number isn't the expected value for this channel, the BEEP peers have lost synchronization. The session then gets terminated without any response, and it is RECOMMENDED that a diagnostic entry be logged 🚨

2.2.1.3 Frame Trailer πŸŽ€

The frame trailer is END followed by a CRLF pair πŸ’œ

When receiving a frame, if the characters right after the payload don't match a trailer, the session is terminated without generating a response, and it is RECOMMENDED that a diagnostic entry be logged. Not fun, but it keeps things honest πŸ™ˆ


2.2.2 Frame Semantics πŸ¦‹

The semantics of each message are channel-specific. So the profile associated with a channel MUST define:

  • the initialization messages, if any, exchanged during channel creation;
  • the messages that MAY be exchanged in the payload of the channel; and,
  • the semantics of these messages.

A profile registration template (Section 5.1) keeps all of this organised for you πŸ“‹

2.2.2.1 Poorly-formed Messages πŸ’…

When defining the behaviour of the profile, the template MUST specify how poorly-formed MSG messages get replied to. For example, the channel management profile sends a negative reply that contains an error message (c.f., Section 2.3.1.5) πŸ’–

If a poorly-formed reply is received on channel zero, the session is terminated without generating a response, and it is RECOMMENDED that a diagnostic entry be logged. Channel zero is the main character, so we don't mess around there πŸ‘‘

If a poorly-formed reply is received on another channel, then that channel MUST be closed using the procedure in Section 2.3.1.3 🧹


2.3 Channel Management 🌈

When a BEEP session starts, only channel number zero is defined, and it's used for channel management. Section 6.1 has the profile registration for BEEP channel management πŸ“–

Channel management lets each BEEP peer advertise the profiles it supports (c.f., Section 2.3.1.1), bind an instance of one of those profiles to a channel (c.f., Section 2.3.1.2), and then later close any channels or release the BEEP session (c.f., Section 2.3.1.3) πŸ”

A BEEP peer SHOULD support at least 257 concurrent channels. Lowkey a big number, but it's the vibe ✨

2.3.1 Message Semantics πŸŽ€

2.3.1.1 The Greeting Message πŸ‘‹

When a BEEP session is established, each BEEP peer shows it's available by immediately sending a positive reply with a message number of zero. That reply contains a greeting element, like so 🧚

    L: <wait for incoming connection>
    I: <open connection>
    L: RPY 0 0 . 0 110
    L: Content-Type: application/beep+xml
    L:
    L: <greeting>
    L:    <profile uri='http://iana.org/beep/TLS' />
    L: </greeting>
    L: END
    I: RPY 0 0 . 0 52
    I: Content-Type: application/beep+xml
    I:
    I: <greeting />
    I: END

Note that this example makes it look like the initiating peer waits until the listening peer sends its greeting. That's just an artifact of how it's presented. In reality, both BEEP peers send their replies independently πŸ™ƒ

The greeting element has two optional attributes (features and localize) and zero or more profile elements. There's one profile element for each profile supported by the BEEP peer acting in a server role πŸ“

  • the features attribute, if present, contains one or more feature tokens, each indicating an optional feature of the channel management profile supported by the BEEP peer;
  • the localize attribute, if present, contains one or more language tokens (defined in [9]), each identifying a desirable language tag for the remote BEEP peer to use when generating textual diagnostics for the close and error elements (the tokens are ordered from most to least desirable); and,
  • each profile element contained within the greeting element identifies a profile. Unlike the profile elements that occur within the start element, the content of each profile element may not contain an optional initialization message.

Section 5.2 defines a registration template for optional features 🌟

2.3.1.2 The Start Message ✨

okay so when a BEEP peer wants to make a brand new channel, it sends a "start" element on channel zero, e.g., πŸŽ€

C: MSG 0 1 . 52 120
C: Content-Type: application/beep+xml
C:
C: <start number='1'>
C:    <profile uri='http://iana.org/beep/SASL/OTP' />
C: </start>
C: END

the "start" element has a "number" attribute, an optional "serverName" attribute, and one or more "profile" elements πŸ’…

  • the "number" attribute indicates the channel number (in the range 1..2147483647) used to identify the channel in future messages;
  • the "serverName" attribute, an arbitrary string, indicates the desired server name for this BEEP session; and,
  • each "profile" element contained with the "start" element has a "uri" attribute, an optional "encoding" attribute, and arbitrary character data as content:
    • the "uri" attribute authoritatively identifies the profile;
    • the "encoding" attribute, if present, specifies whether the content of the "profile" element is represented as a base64-encoded string; and,
    • the content of the "profile" element, if present, MUST be no longer than 4K octets in length and specifies an initialization message given to the channel as soon as it is created.

so channel numbers can't just clash, bestie πŸ™ˆ to avoid conflict when requesting a channel, BEEP peers acting in the initiating role use only positive integers that are odd-numbered, and BEEP peers acting in the listening role use only positive integers that are even-numbered. it's giving organized πŸ¦‹

the "serverName" attribute from the first successful "start" element a BEEP peer receives is meaningful for the duration of the BEEP session. if it's present, the BEEP peer decides whether to operate as the indicated "serverName"; if not, an "error" element is sent in a negative reply. no cap, that's a whole decision moment 😭

when a BEEP peer receives a "start" element on channel zero, it checks each of the proposed profiles and decides whether to use one of them to create the channel. if it does, the matching "profile" element goes back in a positive reply. otherwise, an "error" element goes back in a negative reply 🌸

when the channel is being created, the value of the "serverName" attribute from the first successful "start" element gets consulted for configuration info, e.g., the desired server-side certificate when starting the TLS transport security profile (Section 3.1). main character energy πŸ‘‘

here's what a successful channel creation looks like:

C: MSG 0 1 . 52 178
C: Content-Type: application/beep+xml
C:
C: <start number='1'>
C:    <profile uri='http://iana.org/beep/SASL/OTP' />
C:    <profile uri='http://iana.org/beep/SASL/ANONYMOUS' />
C: </start>
C: END
S: RPY 0 1 . 221 87
S: Content-Type: application/beep+xml
S:
S: <profile uri='http://iana.org/beep/SASL/OTP' />
S: END

and an unsuccessful one, which is so not the vibe πŸ’€

C: MSG 0 1 . 52 120
C: Content-Type: application/beep+xml
C:
C: <start number='2'>
C:    <profile uri='http://iana.org/beep/SASL/OTP' />
C: </start>
C: END
S: ERR 0 1 . 221 127
S: Content-Type: application/beep+xml
S:
S: <error code='501'>number attribute
S: in &lt;start&gt; element must be odd-valued</error>
S: END

finally, here's an example where an initialization element gets exchanged during channel creation 🧚

C: MSG 0 1 . 52 158
C: Content-Type: application/beep+xml
C:
C: <start number='1'>
C:    <profile uri='http://iana.org/beep/TLS'>
C:        <![CDATA[<ready />]]>
C:    </profile>
C: </start>
C: END
S: RPY 0 1 . 110 121
S: Content-Type: application/beep+xml
S:
S: <profile uri='http://iana.org/beep/TLS'>
S:     <![CDATA[<proceed />]]>
S: </profile>
S: END

2.3.1.3 The Close Message 🫢

when a BEEP peer wants to close a channel, it sends a "close" element on channel zero, e.g.,

C: MSG 0 2 . 235 71
C: Content-Type: application/beep+xml
C:
C: <close number='1' code='200' />
C: END

the "close" element has a "number" attribute, a "code" attribute, an optional "xml:lang" attribute, and an optional textual diagnostic as its content πŸ’œ

  • the "number" attribute indicates the channel number;
  • the "code" attribute is a three-digit reply code meaningful to programs (c.f., Section 8);
  • the "xml:lang" attribute identifies the language that the element's content is written in (the value is suggested, but not mandated, by the "localize" attribute of the "greeting" element sent by the remote BEEP peer); and,
  • the textual diagnostic (which may be multiline) is meaningful to implementers, perhaps administrators, and possibly even users, but never programs.

note that if the textual diagnostic is present, then the "xml:lang" attribute is absent only if the language indicated as the remote BEEP peer's first choice is used 🌈

if the "number" attribute is zero, then the BEEP peer wants to release the BEEP session (c.f., Section 2.4). otherwise the "number" attribute refers to an existing channel, and the rest of this section applies.

a BEEP peer MAY send a "close" message for a channel whenever all "MSG" messages it has sent on that channel have been acknowledged. (acknowledgement is when the first frame of a reply gets received by the BEEP peer that sent the MSG "message".)

after sending the "close" message, that BEEP peer MUST NOT send any more "MSG" messages on that channel being closed until the reply to the "close" message has been received (either by an "error" message rejecting the request to close the channel, or by an "ok" message subsequently followed by the channel being successfully started).

NOTE WELL: until a positive reply to the request to close the channel is received, the BEEP peer MUST be prepared to process any "MSG" messages that it receives on that channel.

when a BEEP peer receives a "close" message for a channel, it MAY, at any time, reject the request to close the channel by sending an "error" message in a negative reply.

otherwise, before accepting the request to close the channel and sending an "ok" message in a positive reply, it MUST:

  • finish sending any queued "MSG" messages on that channel of its own;
  • await complete replies to any outstanding "MSG" messages it has sent on that channel; and,
  • finish sending complete replies to any outstanding "MSG" messages it has received on that channel, and ensure that the final frames of those replies have been successfully delivered, i.e.,
    • for transport mappings that guarantee inter-channel ordering of messages, the replies MUST be sent prior to sending the "ok" message in a positive reply; otherwise,
    • the replies MUST be sent and subsequently acknowledged by the underlying transport service prior to sending the "ok" message in a positive reply.

briefly, a successful channel close might look like this πŸ¦‹

C: MSG 0 2 . 235 71
C: Content-Type: application/beep+xml
C:
C: <close number='1' code='200' />
C: END
S: RPY 0 2 . 392 46
S: Content-Type: application/beep+xml
S:
S: <ok />
S: END

and an unsuccessful one πŸ™ˆ

C: MSG 0 2 . 235 71
C: Content-Type: application/beep+xml
C:
C: <close number='1' code='200' />
C: END
S: ERR 0 2 . 392 79
S: Content-Type: application/beep+xml
S:
S: <error code='550'>still working</error>
S: END

2.3.1.4 The OK Message πŸ“

when a BEEP peer agrees to close a channel (or release the BEEP session), it sends an "ok" element in a positive reply.

the "ok" element has no attributes and no content. literally just vibes ✨


2.3.1.5 The Error Message πŸ’€

when a BEEP peer declines the creation of a channel, it sends an "error" element in a negative reply, e.g.,

I: MSG 0 1 . 52 115
I: Content-Type: application/beep+xml
I:
I: <start number='2'>
I:    <profile uri='http://iana.org/beep/FOO' />
I: </start>
I: END
L: ERR 0 1 . 221 105
L: Content-Type: application/beep+xml
L:
L: <error code='550'>all requested profiles are
L: unsupported</error>
L: END

the "error" element has a "code" attribute, an optional "xml:lang" attribute, and an optional textual diagnostic as its content 🌸

  • the "code" attribute is a three-digit reply code meaningful to programs (c.f., Section 8);
  • the "xml:lang" attribute identifies the language that the element's content is written in (the value is suggested, but not mandated, by the "localize" attribute of the "greeting" element sent by the remote BEEP peer); and,
  • the textual diagnostic (which may be multiline) is meaningful to implementers, perhaps administrators, and possibly even users, but never programs.

note that if the textual diagnostic is present, then the "xml:lang" attribute is absent only if the language indicated as the remote BEEP peer's first choice is used.

also, a BEEP peer sends an "error" element whenever:

  • it receives a "MSG" message containing a poorly-formed or unexpected element;
  • it receives a "MSG" message asking to close a channel (or release the BEEP session) and it declines to do so; or
  • a BEEP session is established, the BEEP peer is acting in the listening role, and that BEEP peer is unavailable (in this case, the BEEP acting in the listening role does not send a "greeting" element).

in that last case, both BEEP peers terminate the session, and it is RECOMMENDED that a diagnostic entry be logged by both BEEP peers. it's giving "keep receipts" energy 🧾πŸ”₯

2.4 Session Establishment and Release ✨

okay so when a BEEP session gets set up, each BEEP peer says "hi, I'm here" by immediately sending a positive reply. It's message number zero, on channel zero, and it carries a greeting element πŸ’–

L: <wait for incoming connection>
I: <open connection>
L: RPY 0 0 . 0 110
L: Content-Type: application/beep+xml
L:
L: <greeting>
L:    <profile uri='http://iana.org/beep/TLS' />
L: </greeting>
L: END
I: RPY 0 0 . 0 52
I: Content-Type: application/beep+xml
I:
I: <greeting />
I: END

Alternatively, if the BEEP peer acting in the listening role is unavailable, it sends a negative reply instead πŸ™ˆ

L: <wait for incoming connection>
I: <open connection>
L: ERR 0 0 . 0 60
L: Content-Type: application/beep+xml
L:
L: <error code='421' />
L: END
I: RPY 0 0 . 0 52
I: Content-Type: application/beep+xml
I:
I: <greeting />
I: END
I: <close connection>
L: <close connection>
L: <wait for next connection>

In that case, the greeting element sent by the BEEP peer acting in the initiating role gets ignored. It is RECOMMENDED that a diagnostic entry be logged by both BEEP peers 🧚

Note that both of these examples make it look like the BEEP peer in the initiating role waits until the listening peer sends its greeting. That's just how the presentation works, though. In reality, both BEEP peers send their replies independently πŸ¦‹

When a BEEP peer wants to release the BEEP session, it sends a close element with a zero-valued number attribute on channel zero. The other BEEP peer shows it's cool with that by sending an ok element in a positive reply πŸ’…

C: MSG 0 1 . 52 60
C: Content-Type: application/beep+xml
C:
C: <close code='200' />
C: END
S: RPY 0 1 . 264 46
S: Content-Type: application/beep+xml
S:
S: <ok />
S: END
I: <close connection>
L: <close connection>
L: <wait for next connection>

Alternatively, if the other BEEP peer doesn't want to release the session, the exchange might look like this πŸ‘€

C: MSG 0 1 . 52 60
C: Content-Type: application/beep+xml
C:
C: <close code='200' />
C: END
S: ERR 0 1 . 264 79
S: Content-Type: application/beep+xml
S:
S: <error code='550'>still working</error>
S: END

If session release is declined, the BEEP session SHOULD NOT be terminated, if possible. Very respectful, very iconic 🫢


2.5 Transport Mappings 🌸

Every transport interaction happens inside a session, which is basically a mapping onto one particular transport service. So this memo defines the requirements that MUST be satisfied by any document explaining how a specific transport service makes a BEEP session happen πŸ”₯

2.5.1 Session Management

A BEEP session is connection-oriented. A mapping document MUST define:

  • how a BEEP session is established;
  • how a BEEP peer is identified as acting in the listening role;
  • how a BEEP peer is identified as acting in the initiating role;
  • how a BEEP session is released; and,
  • how a BEEP session is terminated.

2.5.2 Message Exchange

A BEEP session is message-oriented. A mapping document MUST define:

  • how messages are reliably sent and received;
  • how messages on the same channel are received in the same order as they were sent; and,
  • how messages on different channels are sent without ordering constraint.

2.6 Asynchrony πŸ¦‹

BEEP is totally down for asynchronous interactions, both inside one channel and across separate channels. That's what lets you get pipelining (within a channel) and parallelism (between channels). Main character energy πŸ‘‘

2.6.1 Within a Single Channel

A BEEP peer acting in the client role MAY send multiple "MSG" messages on the same channel without waiting for the replies. That's the pipelining bit πŸŽ€

A BEEP peer acting in the server role MUST process all "MSG" messages for a given channel in the same order as they are received. As a consequence, the BEEP peer MUST generate replies in the same order as the corresponding "MSG" messages are received on a given channel. Strict but fair πŸ’œ

Note that in one-to-many exchanges (c.f., Section 2.1.1), the reply to a "MSG" message is made of zero or more "ANS" messages followed by a "NUL" message. In this style of exchange, the "ANS" messages making up the reply MAY be interleaved. When the BEEP peer acting in the server role signals the end of the reply by generating the "NUL" message, it MAY then process the next "MSG" message received for that channel ✨

2.6.2 Between Different Channels

A BEEP peer acting in the client role MAY send multiple "MSG" messages on different channels without waiting for the corresponding replies. The channels run independently, in parallel 🌈

A BEEP peer acting in the server role MAY process "MSG" messages received on different channels in any order it chooses. As a consequence, even though the replies for a given channel look like they were generated in the same order the "MSG" messages arrived, there is no ordering constraint for replies on different channels πŸ’…

2.6.3 Pre-emptive Replies

A BEEP peer acting in the server role MAY send a negative reply before it receives the final "MSG" frame of a message. If it does so, that BEEP peer is obliged to ignore any subsequent "MSG" frames for that message, up to and including the final "MSG" frame πŸ™ˆ

If a BEEP peer acting in the client role receives a negative reply before it sends the final "MSG" frame for a message, then it is REQUIRED to send a "MSG" frame with a continuation status of complete (".") and having a zero-length payload. No skipping that step, bestie 😭

2.6.4 Interference

If processing a particular message affects the sequencing of other messages (either within a channel or between channels), then the corresponding profile SHOULD define this behavior. An example would be a profile whose messages change the underlying transport mapping πŸ“


2.7 Peer-to-Peer Behavior πŸ’–

BEEP is peer-to-peer, so both peers MUST be prepared to receive all messages defined in this memo. An initiating BEEP peer that can only act in the client role MUST behave gracefully if it receives a "MSG" message. Accordingly, all profiles MUST provide an appropriate error message for replying to unexpected "MSG" messages. Be nice, be prepared 🫢

Because BEEP is peer-to-peer, message numbers are unidirectionally-significant. The message numbers in "MSG" messages sent by a BEEP peer acting in the initiating role have nothing to do with the message numbers in "MSG" messages sent by a BEEP peer acting in the listening role. Two separate timelines, no drama 🌸

For example, these two messages

I: MSG 0 1 . 52 120
I: Content-Type: application/beep+xml
I:
I: <start number='1'>
I:    <profile uri='http://iana.org/beep/SASL/OTP' />
I: </start>
I: END
L: MSG 0 1 . 221 116
L: Content-Type: application/beep+xml
L:
L: <start number='2'>
L:    <profile uri='http://iana.org/beep/APEX' />
L: </start>
L: END

refer to different messages sent on channel zero 🧚


3. Transport Security πŸ”

When a BEEP session is established, the transfer is plaintext, with no privacy. So transport security in BEEP is achieved using an initial tuning profile πŸŽ€

This document defines one profile:

  • the TLS transport security profile, based on TLS version one [3].

Other profiles MAY be defined and deployed on a bilateral basis. Also, because they're so tied to the transport service, a given transport security profile tends to be relevant to a single transport mapping (c.f., Section 2.5) πŸ¦‹

When a channel associated with transport security begins the underlying negotiation process, all channels (including channel zero) are closed on the BEEP session. So once the negotiation finishes, regardless of how it went, both BEEP peers issue a new greeting. (If the negotiation fails, then either BEEP peer MAY instead terminate the session, and it is RECOMMENDED that a diagnostic entry be logged.) 😭

A BEEP peer MAY choose to issue different greetings depending on whether privacy is in use, e.g.,

L: <wait for incoming connection>
I: <open connection>
L: RPY 0 0 . 0 110
L: Content-Type: application/beep+xml
L:
L: <greeting>
L:    <profile uri='http://iana.org/beep/TLS' />
L: </greeting>
L: END
I: RPY 0 0 . 0 52
I: Content-Type: application/beep+xml
I:
I: <greeting />
I: END
I: MSG 0 1 . 52 158
I: Content-Type: application/beep+xml
I:

I: <start number='1'>
I:    <profile uri='http://iana.org/beep/TLS'>
I:        <![CDATA[<ready />]]>
I:    </profile>
I: </start>
I: END
L: RPY 0 1 . 110 121
L: Content-Type: application/beep+xml
L:
L: <profile uri='http://iana.org/beep/TLS'>
L:     <![CDATA[<proceed />]]>
L: </profile>
L: END

    ... successful transport security negotiation ...

L: RPY 0 0 . 0 221
L: Content-Type: application/beep+xml
L:
L: <greeting>
L:    <profile uri='http://iana.org/beep/SASL/ANONYMOUS' />
L:    <profile uri='http://iana.org/beep/SASL/OTP' />
L:    <profile uri='http://iana.org/beep/APEX' />
L: </greeting>
L: END
I: RPY 0 0 . 0 52
I: Content-Type: application/beep+xml
I:
I: <greeting />
I: END

Of course, not every BEEP peer needs to be this single-minded πŸ’…

L: <wait for incoming connection>
I: <open connection>
L: RPY 0 0 . 0 268
L: Content-Type: application/beep+xml
L:
L: <greeting>
L:    <profile uri='http://iana.org/beep/SASL/ANONYMOUS' />
L:    <profile uri='http://iana.org/beep/SASL/OTP' />
L:    <profile uri='http://iana.org/beep/APEX' />
L:    <profile uri='http://iana.org/beep/TLS' />
L: </greeting>
L: END
I: RPY 0 0 . 0 52
I: Content-Type: application/beep+xml
I:

I: <greeting />
I: END
I: MSG 0 1 . 52 158
I: Content-Type: application/beep+xml
I:
I: <start number='1'>
I:    <profile uri='http://iana.org/beep/TLS'>
I:        <![CDATA[<ready />]]>
I:    </profile>
I: </start>
I: END
L: RPY 0 1 . 268 121
L: Content-Type: application/beep+xml
L:
L: <profile uri='http://iana.org/beep/TLS'>
L:     <![CDATA[<proceed />]]>
L: </profile>
L: END

    ... failed transport security negotiation ...

L: RPY 0 0 . 0 268
L: Content-Type: application/beep+xml
L:
L: <greeting>
L:    <profile uri='http://iana.org/beep/SASL/ANONYMOUS' />
L:    <profile uri='http://iana.org/beep/SASL/OTP' />
L:    <profile uri='http://iana.org/beep/APEX' />
L:    <profile uri='http://iana.org/beep/TLS' />
L: </greeting>
L: END
I: RPY 0 0 . 0 52
I: Content-Type: application/beep+xml
I:
I: <greeting />
I: END

3.1 The TLS Transport Security Profile 🌷

Section 6.2 has the registration for this profile. Go check it out 🌈

3.1.1 Profile Identification and Initialization πŸŽ€

okay so the TLS transport security profile is identified as http://iana.org/beep/TLS πŸ’–

and that goes in the BEEP "profile" element during channel creation. during channel creation, the matching "profile" element in the BEEP "start" element may contain a "ready" element. if channel creation works, then before sending the reply, the BEEP peer processes the "ready" element and puts the result in the reply, like this:

C: MSG 0 1 . 52 158
C: Content-Type: application/beep+xml
C:
C: <start number='1'>
C:    <profile uri='http://iana.org/beep/TLS'>
C:        <![CDATA[<ready />]]>
C:    </profile>
C: </start>
C: END
S: RPY 0 1 . 110 121
S: Content-Type: application/beep+xml
S:
S: <profile uri='http://iana.org/beep/TLS'>
S:     <![CDATA[<proceed />]]>
S: </profile>
S: END

btw it's totally possible for the channel to get created but the encapsulated operation to flop 😭 like this:

C: MSG 0 1 . 52 173
C: Content-Type: application/beep+xml
C:
C: <start number='1'>
C:    <profile uri='http://iana.org/beep/TLS'>
C:        <![CDATA[<ready version="oops" />]]>
C:    </profile>
C: </start>
C: END
S: RPY 0 1 . 110 193
S: Content-Type: application/beep+xml
S:
S: <profile uri='http://iana.org/beep/TLS'>
S:     <![CDATA[<error code='501'>version attribute
S: poorly formed in &lt;ready&gt; element</error>]]>
S: </profile>
S: END

in this case the positive reply still goes out (the channel did get created βœ…), but the encapsulated response tells you exactly why the operation failed. the receipts are right there, bestie πŸ’…

3.1.2 Message Syntax 🧚

Section 7.2 defines the messages that are used in the TLS transport security profile. go check it out, it's giving structure πŸ“œ

3.1.3 Message Semantics 🌸

3.1.3.1 The Ready Message 🫢

The "ready" element has an optional "version" attribute and no content:

  • the "version" element defines the earliest version of TLS acceptable for use.

ok so when a BEEP peer sends the "ready" element, it must not send any further traffic on the underlying transport service until a corresponding reply ("proceed" or "error") is received. and the receiving BEEP peer? it has to wait until any pending replies have been generated and sent before it processes a "ready" element. patience is a whole vibe 🐒✨

3.1.3.2 The Proceed Message πŸ¦‹

The "proceed" element has no attributes and no content. it gets sent as a reply to the "ready" element.

when a BEEP peer receives the "ready" element, it must not send any further traffic on the underlying transport service until it generates a corresponding reply. if the BEEP peer decides to allow transport security negotiation, it implicitly closes all channels (including channel zero), sends the "proceed" element, and then waits for the underlying negotiation process for transport security. πŸ”

when a BEEP peer receives a "proceed" element in reply to its "ready" message, it implicitly closes all channels (including channel zero), and immediately begins the underlying negotiation process for transport security. the handshake era has officially started πŸ”₯

4. User Authentication ✨

when a BEEP session is established, anonymous access, without trace information, is provided. so, user authentication in BEEP is achieved using an initial tuning profile. it's giving incognito mode πŸ•ΆοΈ

this document defines a family of profiles based on SASL mechanisms:

  • each mechanism in the IANA SASL registry [15] has an associated profile.

other profiles may be defined and deployed on a bilateral basis 🀝

whenever a successful authentication occurs, on any channel, the authenticated identity is updated for all existing and future channels on the BEEP session. further, no additional attempts at authentication are allowed. one and done, main character energy πŸ‘‘

note that regardless of transport security and user authentication, authorization is an internal matter for each BEEP peer. so each peer may choose to restrict the operations it allows based on the authentication credentials provided (i.e., unauthorized operations might be rejected with error code 530). the bouncer at the door is each peer's call πŸ’…πŸšͺ

4.1 The SASL Family of Profiles 🌈

Section 6.3 contains the registration for this profile.

note that SASL may provide both user authentication and transport security. once transport security is successfully negotiated for a BEEP session, a SASL security layer must not be negotiated. similarly, once any SASL negotiation is successful, a transport security profile must not begin its underlying negotiation process. you can't double-dip on security, no cap πŸ™…β€β™€οΈ

Section 4 of the SASL specification [4] requires the following information be supplied by a protocol definition:

  • service name: "beep"
  • initiation sequence: creating a channel using a BEEP profile corresponding to a SASL mechanism starts the exchange. an optional parameter corresponding to the "initial response" sent by the client is carried within a "blob" element during channel creation.
  • exchange sequence: "challenges" and "responses" are carried in exchanges of the "blob" element. the "status" attribute of the "blob" element is used both by a server indicating a successful completion of the exchange, and a client aborting the exchange, The server indicates failure of the exchange by sending an "error" element.
  • security layer negotiation: when a security layer starts negotiation, all channels (including channel zero) are closed on the BEEP session. so, upon completion of the negotiation process, regardless of its outcome, a new greeting is issued by both BEEP peers. fresh start, every time πŸ“

if a security layer is successfully negotiated, it takes effect immediately following the message that concludes the server's successful completion reply.

  • use of the authorization identity: this is made available to all channels for the duration of the BEEP session.

4.1.1 Profile Identification and Initialization πŸ’œ

each SASL mechanism registered with the IANA is identified as:

http://iana.org/beep/SASL/mechanism

where "MECHANISM" is the token assigned to that mechanism by the IANA.

ok so during channel creation, a BEEP peer may provide multiple profiles to the remote peer, like this:

C: MSG 0 1 . 52 178
C: Content-Type: application/beep+xml
C:
C: <start number='1'>
C:    <profile uri='http://iana.org/beep/SASL/ANONYMOUS' />
C:    <profile uri='http://iana.org/beep/SASL/OTP' />
C: </start>
C: END
S: RPY 0 1 . 221 87
S: Content-Type: application/beep+xml
S:
S: <profile uri='http://iana.org/beep/SASL/OTP' />
S: END

during channel creation, the matching "profile" element in the BEEP "start" element may contain a "blob" element. again, it's possible for the channel to be created but the encapsulated operation to fail 😭

C: MSG 0 1 . 52 183
C: Content-Type: application/beep+xml
C:
C: <start number='1'>
C:    <profile uri='http://iana.org/beep/SASL/OTP'>
C:        <![CDATA[<blob>AGJsb2NrbWFzdGVy</blob>]]>
C:    </profile>
C: </start>
C: END
S: RPY 0 1 . 221 178
S: Content-Type: application/beep+xml
S:
S: <profile uri='http://iana.org/beep/SASL/OTP'>
S:     <![CDATA[<error code='534'>authentication mechanism is
S: too weak</error>]]>
S: </profile>
S: END

in this case a positive reply is sent (channel creation succeeded), but the encapsulated response says why the operation failed. the positive reply is still the official "yes, you're in" πŸŽ‰

otherwise, the server sends a challenge (or signifies success), like this:

C: MSG 0 1 . 52 183
C: Content-Type: application/beep+xml
C:
C: <start number='1'>
C:    <profile uri='http://iana.org/beep/SASL/OTP'>
C:        <![CDATA[<blob>AGJsb2NrbWFzdGVy</blob>]]>
C:    </profile>
C: </start>
C: END
S: RPY 0 1 . 221 171
S: Content-Type: application/beep+xml
S:
S: <profile uri='http://iana.org/beep/SASL/OTP'>
S:    <![CDATA[<blob>b3RwLXNoYTEgOTk5NyBwaXh5bWlzYXM4NTgwNSBleHQ=
                                                              </blob>]]>
S: </profile>
S: END

note that this example implies that the "blob" element in the server's reply appears on two lines. this is just an artifact of the presentation. in fact, only one line is used πŸ™ˆ

if a challenge is received, then the client responds and waits for another reply, like this:

C: MSG 1 0 . 0 97
C: Content-Type: application/beep+xml
C:
C: <blob>d29yZDpmZXJuIGhhbmcgYnJvdyBib25nIGhlcmQgdG9n</blob>
C: END
S: RPY 1 0 . 0 66
S: Content-Type: application/beep+xml
S:
S: <blob status='complete' />
S: END

of course, the client could abort the authentication process by sending <blob status='abort' /> instead.

or, the server might reject the response with an error, e.g.,

C: MSG 1 0 . 0 97
C: Content-Type: application/beep+xml
C:
C: <blob>d29yZDpmZXJuIGhhbmcgYnJvdyBib25nIGhlcmQgdG9n</blob>
C: END
S: ERR 1 0 . 0 60
S: Content-Type: application/beep+xml
S:
S: <error code='535' />
S: END

finally, depending on the SASL mechanism, an initialization element may be exchanged unidirectionally during channel creation, like this:

C: MSG 0 1 . 52 125
C: Content-Type: application/beep+xml
C:
C: <start number='1'>
C:    <profile uri='http://iana.org/beep/SASL/CRAM-MD5' />
C: </start>
C: END
S: RPY 0 1 . 221 185
S: Content-Type: application/beep+xml
S:
S: <profile uri='http://iana.org/beep/SASL/CRAM-MD5'>
S: <![CDATA[<blob>PDE4OTYuNjk3MTcwOTUyQHBvc3RvZmZpY2UucmVzdG9uLm1
                                                     jaS5uZXQ+</blob>]]>
S: </profile>
S: END

note that this example implies that the "blob" element in the server's reply appears on two lines. again, that's just presentation, and only one line is actually used ✨

4.1.2 Message Syntax πŸŽ€

Section 7.3 defines the messages that are used for each profile in the SASL family.

also, because many SASL mechanisms exchange binary data, the content of the "blob" element is always a base64-encoded string. base64 is the unsung hero of this whole section πŸ¦‹πŸ’–

4.1.3. Message Semantics

okay so the "blob" element has an optional "status" attribute πŸ’… and its content is just arbitrary octets 🫢

  • the "status" attribute, if present, takes one of three values:
    • abort: used by a client to say it's bailing on the authentication process πŸ™…β€β™€οΈ
    • complete: used by a server to say the exchange is done and successful ✨
    • continue: used by either a client or server, otherwise πŸ”

okay and now the important bit πŸ‘€ SASL's EXTERNAL mechanism works with an "external authentication" service, and that service is provided by one of:

  • a transport security profile, capable of providing authentication information (e.g., Section 3.1), being active on the connection;
  • a network service, capable of providing strong authentication (e.g., IPSec [12]), underlying the connection; or,
  • a locally-defined security service.

for authentication to succeed, two conditions must hold 🧐

  • an external authentication service must be active; and,
  • if present, the authentication identity must be consistent with the credentials provided by the external authentication service (if the authentication identity is empty, then an authorization identity is automatically derived from the credentials provided by the external authentication service).

5. Registration Templates πŸ“‹

5.1. Profile Registration Template

when a profile gets registered, these are the details that get supplied πŸ“

  • Profile Identification: specify a URI [10] that authoritatively identifies this profile.
  • Message Exchanged during Channel Creation: specify the datatypes that may be exchanged during channel creation.
  • Messages starting one-to-one exchanges: specify the datatypes that may be present when an exchange starts.
  • Messages in positive replies: specify the datatypes that may be present in a positive reply.
  • Messages in negative replies: specify the datatypes that may be present in a negative reply.
  • Messages in one-to-many exchanges: specify the datatypes that may be present in a one-to-many exchange.
  • Message Syntax: specify the syntax of the datatypes exchanged by the profile.
  • Message Semantics: specify the semantics of the datatypes exchanged by the profile.
  • Contact Information: specify the postal and electronic contact information for the author of the profile.

5.2. Feature Registration Template

same energy but for features of the channel management profile πŸŽ€ when one gets registered, you supply:

  • Feature Identification: specify a string that identifies this feature. Unless the feature is registered with the IANA, the feature's identification must start with "x-".
  • Feature Semantics: specify the semantics of the feature.
  • Contact Information: specify the postal and electronic contact information for the author of the feature.

6. Initial Registrations 🌸

6.1. Registration: BEEP Channel Management

  • Profile Identification: not applicable
  • Messages exchanged during Channel Creation: not applicable
  • Messages starting one-to-one exchanges: "start" or "close"
  • Messages in positive replies: "greeting", "profile", or "ok"
  • Messages in negative replies: "error"
  • Messages in one-to-many exchanges: none
  • Message Syntax: c.f., Section 7.1
  • Message Semantics: c.f., Section 2.3.1
  • Contact Information: c.f., the "Author's Address" section of this memo

6.2. Registration: TLS Transport Security Profile

  • Profile Identification: http://iana.org/beep/TLS
  • Messages exchanged during Channel Creation: "ready"
  • Messages starting one-to-one exchanges: "ready"
  • Messages in positive replies: "proceed"
  • Messages in negative replies: "error"
  • Messages in one-to-many exchanges: none
  • Message Syntax: c.f., Section 7.2
  • Message Semantics: c.f., Section 3.1.3
  • Contact Information: c.f., the "Author's Address" section of this memo

6.3. Registration: SASL Family of Profiles

  • Profile Identification: http://iana.org/beep/SASL/mechanism, where "mechanism" is a token registered with the IANA
  • Messages exchanged during Channel Creation: "blob"
  • Messages starting one-to-one exchanges: "blob"
  • Messages in positive replies: "blob"
  • Messages in negative replies: "error"
  • Messages in one-to-many exchanges: none
  • Message Syntax: c.f., Section 7.3
  • Message Semantics: c.f., Section 4.1.3
  • Contact Information: c.f., the "Author's Address" section of this memo

6.4. Registration: application/beep+xml

this one's the media type registration, so it gets a little more formal 🎩✨

  • MIME media type name: application
  • MIME subtype name: beep+xml
  • Required parameters: none
  • Optional parameters: charset (defaults to "UTF-8" [13])
  • Encoding considerations: This media type may contain binary content; accordingly, when used over a transport that does not permit binary transfer, an appropriate encoding must be applied
  • Security considerations: none, per se; however, any BEEP profile which uses this media type must describe its relevant security considerations
  • Interoperability considerations: n/a
  • Published specification: This media type is a proper subset of the the XML 1.0 specification [2]. Two restrictions are made.

First, no entity references other than the five predefined general entities references ("&amp;", "&lt;", "&gt;", "&apos;", and "&quot;") and numeric entity references may be present.

Second, neither the "XML" declaration (e.g., <?xml version="1.0" ?>) nor the "DOCTYPE" declaration (e.g., <!DOCTYPE ...>) may be present. (Accordingly, if another character set other than UTF-8 is desired, then the "charset" parameter must be present.)

All other XML 1.0 instructions (e.g., CDATA blocks, processing instructions, and so on) are allowed.

  • Applications which use this media type: any BEEP profile wishing to make use of this XML 1.0 subset
  • Additional Information: none
  • Contact for further information: c.f., the "Author's Address" section of this memo
  • Intended usage: limited use
  • Author/Change controller: the IESG

7. DTDs 🧚

7.1. BEEP Channel Management DTD

this is the DTD for BEEP channel management, as of 2000-10-29 πŸ’œ

<!--
  DTD for BEEP Channel Management, as of 2000-10-29


  Refer to this DTD as:

    <!ENTITY % BEEP PUBLIC "-//IETF//DTD BEEP//EN"
               "http://xml.resource.org/profiles/BEEP/beep.dtd">
    %BEEP;
  -->


<!--
  DTD data types:

        entity        syntax/reference     example
        ======        ================     =======
    a channel number
        CHAN          1..2147483647        1

    authoritative profile identification
        URI          c.f., [RFC-2396]      http://invisible.net/

    one or more feature tokens, separated by space
        FTRS         NMTOKENS              "magic"

    a language tag
        LANG         c.f., [RFC-1766]      "en", "en-US", etc.

    zero or more language tags
        LOCS         NMTOKENS              "en-US"

    a 3-digit reply code
        XYZ           [1-5][0-9][0-9]      500
  -->


<!ENTITY % CHAN       "CDATA">
<!ENTITY % URI        "CDATA">
<!ENTITY % FTRS       "NMTOKENS">
<!ENTITY % LANG       "NMTOKEN">
<!ENTITY % LOCS       "NMTOKEN">
<!ENTITY % XYZ        "CDATA">
<!--
  BEEP messages, exchanged as application/beep+xml

     role       MSG         RPY         ERR
    =======     ===         ===         ===
    I and L                 greeting    error

    I or L      start       profile     error

    I or L      close       ok          error
  -->


<!ELEMENT greeting    (profile)*>
<!ATTLIST greeting
          features    %FTRS;            #IMPLIED
          localize    %LOCS;            "i-default">

<!ELEMENT start       (profile)+>
<!ATTLIST start
          number      %CHAN;             #REQUIRED
          serverName  CDATA              #IMPLIED>

<!-- profile element is empty if contained in a greeting -->
<!ELEMENT profile     (#PCDATA)>
<!ATTLIST profile
          uri         %URI;              #REQUIRED
          encoding    (none|base64)      "none">

<!ELEMENT close       (#PCDATA)>
<!ATTLIST close
          number      %CHAN;             "0"
          code        %XYZ;              #REQUIRED
          xml:lang    %LANG;             #IMPLIED>

<!ELEMENT ok          EMPTY>

<!ELEMENT error       (#PCDATA)>
<!ATTLIST error
          code        %XYZ;              #REQUIRED
          xml:lang    %LANG;             #IMPLIED>

7.2. TLS Transport Security Profile DTD

the TLS profile DTD, as of 2000-09-04 πŸ”

<!--
  DTD for the TLS Transport Security Profile, as of 2000-09-04


  Refer to this DTD as:

    <!ENTITY % TLS PUBLIC "-//IETF//DTD TLS//EN"
               "http://xml.resource.org/profiles/TLS/tls.dtd">
    %TLS;
  -->


<!--
  TLS messages, exchanged as application/beep+xml

     role       MSG         RPY         ERR
    ======      ===         ===         ===
    I or L      ready       proceed     error
  -->


<!ELEMENT ready       EMPTY>
<!ATTLIST ready
          version     CDATA              "1">

<!ELEMENT proceed     EMPTY>

7.3. SASL Family of Profiles DTD

and last but not least, the SASL family DTD 🫧

<!--
  DTD for the SASL Family of Profiles, as of 2000-09-04


  Refer to this DTD as:

    <!ENTITY % SASL PUBLIC "-//IETF//DTD SASL//EN"
               "http://xml.resource.org/profiles/sasl/sasl.dtd">
    %SASL;
  -->


<!--
  SASL messages, exchanged as application/beep+xml

     role       MSG         RPY         ERR
    ======      ===         ===         ===
    I or L      blob        blob        error
  -->


<!ELEMENT blob        (#PCDATA)>
<!ATTLIST blob
          xml:space   (default|preserve)
                                        "preserve"
          status      (abort|complete|continue)
                                         "continue">

8. Reply Codes 🚦

these are the reply codes, with what each one means πŸ’…

code    meaning
====    =======
200     success

421     service not available

450     requested action not taken
        (e.g., lock already in use)

451     requested action aborted
        (e.g., local error in processing)

454     temporary authentication failure

500     general syntax error
        (e.g., poorly-formed XML)

501     syntax error in parameters
        (e.g., non-valid XML)

504     parameter not implemented

530     authentication required

534     authentication mechanism insufficient
        (e.g., too weak, sequence exhausted, etc.)

535     authentication failure

537     action not authorized for user

538     authentication mechanism requires encryption

550     requested action not taken
        (e.g., no requested profiles are acceptable)

553     parameter invalid

554     transaction failed
        (e.g., policy violation)

9. Security Considerations πŸ”’βœ¨

okay bestie, this is the serious bit 😭 The BEEP framing mechanism, per se, provides no protection against attack πŸ’€. However, judicious use of initial tuning profiles gives you varying degrees of assurance, so let's break it down 🫢:

  1. If you're using one of the profiles from the SASL family, go read [4]'s Section 9 for the full security deep dive πŸ“–.
  2. If the TLS transport security profile is used (or if a SASL security layer is negotiated), then:
    1. A man-in-the-middle 😈 can remove the security-related profiles from the BEEP greeting, or generate a negative reply to the "ready" element of the TLS transport security profile πŸ™ˆ. A BEEP peer may be configurable to refuse to proceed without an acceptable level of privacy πŸ›‘οΈ.
    2. A man-in-the-middle can cause a down-negotiation to the weakest cipher suite available πŸ’€. A BEEP peer should be configurable to refuse weak cipher suites πŸ”’.
    3. A man-in-the-middle can modify any protocol exchanges prior to a successful negotiation 😭. Upon completing the negotiation, a BEEP peer must discard previously cached information about the BEEP session 🧹.

As different TLS ciphersuites provide varying levels of security, administrators should carefully choose which ciphersuites are provisioned πŸŽ€.

As BEEP is peer-to-peer in nature πŸ¦‹, before performing any task associated with a message, each channel should apply the appropriate access control based on the authenticated identity and privacy level associated with the BEEP session πŸ‘‘.


References πŸ“š

[1] Freed, N. and N. Borenstein, "Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies", RFC 2045, November 1996.

[2] World Wide Web Consortium, "Extensible Markup Language (XML) 1.0", W3C XML, February 1998, <http://www.w3.org/TR/1998/REC-xml-19980210>.

[3] Dierks, T., Allen, C., Treese, W., Karlton, P., Freier, A. and P. Kocher, "The TLS Protocol Version 1.0", RFC 2246, January 1999.

[4] Myers, J., "Simple Authentication and Security Layer (SASL)", RFC 2222, October 1997.

[5] Rose, M., "Mapping the BEEP Core onto TCP", RFC 3081, March 2001.

[6] Postel, J., "Transmission Control Protocol", STD 7, RFC 793, September 1981.

[7] Crocker, D. and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", RFC 2234, November 1997.

[8] Elz, R. and R. Bush, "Serial Number Arithmetic", RFC 1982, August 1996.

[9] Alvestrand, H., "Tags for the Identification of Languages", RFC BCP 47, RFC 3066, January 2001.

[10] Berners-Lee, T., Fielding, R. and L. Masinter, "Uniform Resource Identifiers (URI): Generic Syntax", RFC 2396, August 1998.

[11] Newman, C., "The One-Time-Password SASL Mechanism", RFC 2444, October 1998.

[12] Kent, S. and R. Atkinson, "Security Architecture for the Internet Protocol", RFC 2401, November 1998.

[13] Yergeau, F., "UTF-8, a transformation format of ISO 10646", RFC 2279, January 1998.

[14] Linn, J., "Generic Security Service Application Program Interface, Version 2", RFC 2078, January 1997.

[15] <http://www.isi.edu/in-notes/iana/assignments/sasl-mechanisms>


Author's Address πŸ–‹οΈ

Marshall T. Rose
Invisible Worlds, Inc.
1179 North McDowell Boulevard
Petaluma, CA  94954-6559
US

Phone: +1 707 789 3700
EMail: mrose@invisible.net
URI:   http://invisible.net/

Appendix A. Acknowledgements πŸ™

big thanks to everyone the author gratefully acknowledges for their contributions: David Clark, Dave Crocker, Steve Deering, Wesley Michael Eddy, Huston Franklin, Marco Gazzetta, Danny Goodman, Steve Harris, Robert Herriot, Ken Hirsch, Greg Hudson, Ben Laurie, Carl Malamud, Michael Mealling, Keith McCloghrie, Paul Mockapetris, RL 'Bob' Morgan, Frank Morton, Darren New, Chris Newman, Joe Touch, Paul Vixie, Gabe Wachob, Daniel Woods, and, James Woodyatt. πŸ’– In particular, Dave Crocker gave super helpful suggestions on the nature of segmentation in the framing mechanism 🧠✨.

Appendix B. IANA Considerations 🌸

The IANA registers "beep" as a GSSAPI [14] service name, as specified in Section 4.1.

The IANA maintains a list of:

  • standards-track BEEP profiles, c.f., Section 5.1; and,
  • standards-track features for the channel management profile, c.f., Section 5.2.

For each list, the IESG is responsible for assigning a designated expert to review the specification prior to the IANA making the assignment. As a courtesy to developers of non-standards track BEEP profiles and channel management features, the mailing list bxxpwg@invisible.net may be used to solicit commentary πŸ’¬.

The IANA makes the registrations specified in Section 6.2 and Section 6.3. It is recommended that the IANA register these profiles using the IANA as a URI-prefix, and populate those URIs with the respective profile registrations πŸ¦‹.

Copyright (C) The Internet Society (2001). All Rights Reserved.

This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Internet Society or other Internet organizations, except as needed for the purpose of developing Internet standards in which case the procedures for copyrights defined in the Internet Standards process must be followed, or as required to translate it into languages other than English.

The limited permissions granted above are perpetual and will not be revoked by the Internet Society or its successors or assigns.

This document and the information contained herein is provided on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

Acknowledgement πŸ’…

Funding for the RFC Editor function is currently provided by the Internet Society. 🌈

πŸ“¦ where this page comes from