summaryrefslogtreecommitdiffstats
path: root/PROTOCOL
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--PROTOCOL499
-rw-r--r--PROTOCOL.agent5
-rw-r--r--PROTOCOL.certkeys306
-rw-r--r--PROTOCOL.chacha20poly1305107
-rw-r--r--PROTOCOL.key68
-rw-r--r--PROTOCOL.krl171
-rw-r--r--PROTOCOL.mux298
7 files changed, 1454 insertions, 0 deletions
diff --git a/PROTOCOL b/PROTOCOL
new file mode 100644
index 0000000..f75c1c0
--- /dev/null
+++ b/PROTOCOL
@@ -0,0 +1,499 @@
+This documents OpenSSH's deviations and extensions to the published SSH
+protocol.
+
+Note that OpenSSH's sftp and sftp-server implement revision 3 of the SSH
+filexfer protocol described in:
+
+https://www.openssh.com/txt/draft-ietf-secsh-filexfer-02.txt
+
+Newer versions of the draft will not be supported, though some features
+are individually implemented as extensions described below.
+
+The protocol used by OpenSSH's ssh-agent is described in the file
+PROTOCOL.agent
+
+1. Transport protocol changes
+
+1.1. transport: Protocol 2 MAC algorithm "umac-64@openssh.com"
+
+This is a new transport-layer MAC method using the UMAC algorithm
+(rfc4418). This method is identical to the "umac-64" method documented
+in:
+
+https://www.openssh.com/txt/draft-miller-secsh-umac-01.txt
+
+1.2. transport: Protocol 2 compression algorithm "zlib@openssh.com"
+
+This transport-layer compression method uses the zlib compression
+algorithm (identical to the "zlib" method in rfc4253), but delays the
+start of compression until after authentication has completed. This
+avoids exposing compression code to attacks from unauthenticated users.
+
+The method is documented in:
+
+https://www.openssh.com/txt/draft-miller-secsh-compression-delayed-00.txt
+
+1.3. transport: New public key algorithms "ssh-rsa-cert-v01@openssh.com",
+ "ssh-dsa-cert-v01@openssh.com",
+ "ecdsa-sha2-nistp256-cert-v01@openssh.com",
+ "ecdsa-sha2-nistp384-cert-v01@openssh.com" and
+ "ecdsa-sha2-nistp521-cert-v01@openssh.com"
+
+OpenSSH introduces new public key algorithms to support certificate
+authentication for users and host keys. These methods are documented
+in the file PROTOCOL.certkeys
+
+1.4. transport: Elliptic Curve cryptography
+
+OpenSSH supports ECC key exchange and public key authentication as
+specified in RFC5656. Only the ecdsa-sha2-nistp256, ecdsa-sha2-nistp384
+and ecdsa-sha2-nistp521 curves over GF(p) are supported. Elliptic
+curve points encoded using point compression are NOT accepted or
+generated.
+
+1.5 transport: Protocol 2 Encrypt-then-MAC MAC algorithms
+
+OpenSSH supports MAC algorithms, whose names contain "-etm", that
+perform the calculations in a different order to that defined in RFC
+4253. These variants use the so-called "encrypt then MAC" ordering,
+calculating the MAC over the packet ciphertext rather than the
+plaintext. This ordering closes a security flaw in the SSH transport
+protocol, where decryption of unauthenticated ciphertext provided a
+"decryption oracle" that could, in conjunction with cipher flaws, reveal
+session plaintext.
+
+Specifically, the "-etm" MAC algorithms modify the transport protocol
+to calculate the MAC over the packet ciphertext and to send the packet
+length unencrypted. This is necessary for the transport to obtain the
+length of the packet and location of the MAC tag so that it may be
+verified without decrypting unauthenticated data.
+
+As such, the MAC covers:
+
+ mac = MAC(key, sequence_number || packet_length || encrypted_packet)
+
+where "packet_length" is encoded as a uint32 and "encrypted_packet"
+contains:
+
+ byte padding_length
+ byte[n1] payload; n1 = packet_length - padding_length - 1
+ byte[n2] random padding; n2 = padding_length
+
+1.6 transport: AES-GCM
+
+OpenSSH supports the AES-GCM algorithm as specified in RFC 5647.
+Because of problems with the specification of the key exchange
+the behaviour of OpenSSH differs from the RFC as follows:
+
+AES-GCM is only negotiated as the cipher algorithms
+"aes128-gcm@openssh.com" or "aes256-gcm@openssh.com" and never as
+an MAC algorithm. Additionally, if AES-GCM is selected as the cipher
+the exchanged MAC algorithms are ignored and there doesn't have to be
+a matching MAC.
+
+1.7 transport: chacha20-poly1305@openssh.com authenticated encryption
+
+OpenSSH supports authenticated encryption using ChaCha20 and Poly1305
+as described in PROTOCOL.chacha20poly1305.
+
+1.8 transport: curve25519-sha256@libssh.org key exchange algorithm
+
+OpenSSH supports the use of ECDH in Curve25519 for key exchange as
+described at:
+http://git.libssh.org/users/aris/libssh.git/plain/doc/curve25519-sha256@libssh.org.txt?h=curve25519
+
+2. Connection protocol changes
+
+2.1. connection: Channel write close extension "eow@openssh.com"
+
+The SSH connection protocol (rfc4254) provides the SSH_MSG_CHANNEL_EOF
+message to allow an endpoint to signal its peer that it will send no
+more data over a channel. Unfortunately, there is no symmetric way for
+an endpoint to request that its peer should cease sending data to it
+while still keeping the channel open for the endpoint to send data to
+the peer.
+
+This is desirable, since it saves the transmission of data that would
+otherwise need to be discarded and it allows an endpoint to signal local
+processes of the condition, e.g. by closing the corresponding file
+descriptor.
+
+OpenSSH implements a channel extension message to perform this
+signalling: "eow@openssh.com" (End Of Write). This message is sent by
+an endpoint when the local output of a session channel is closed or
+experiences a write error. The message is formatted as follows:
+
+ byte SSH_MSG_CHANNEL_REQUEST
+ uint32 recipient channel
+ string "eow@openssh.com"
+ boolean FALSE
+
+On receiving this message, the peer SHOULD cease sending data of
+the channel and MAY signal the process from which the channel data
+originates (e.g. by closing its read file descriptor).
+
+As with the symmetric SSH_MSG_CHANNEL_EOF message, the channel does
+remain open after a "eow@openssh.com" has been sent and more data may
+still be sent in the other direction. This message does not consume
+window space and may be sent even if no window space is available.
+
+NB. due to certain broken SSH implementations aborting upon receipt
+of this message (in contravention of RFC4254 section 5.4), this
+message is only sent to OpenSSH peers (identified by banner).
+Other SSH implementations may be whitelisted to receive this message
+upon request.
+
+2.2. connection: disallow additional sessions extension
+ "no-more-sessions@openssh.com"
+
+Most SSH connections will only ever request a single session, but a
+attacker may abuse a running ssh client to surreptitiously open
+additional sessions under their control. OpenSSH provides a global
+request "no-more-sessions@openssh.com" to mitigate this attack.
+
+When an OpenSSH client expects that it will never open another session
+(i.e. it has been started with connection multiplexing disabled), it
+will send the following global request:
+
+ byte SSH_MSG_GLOBAL_REQUEST
+ string "no-more-sessions@openssh.com"
+ char want-reply
+
+On receipt of such a message, an OpenSSH server will refuse to open
+future channels of type "session" and instead immediately abort the
+connection.
+
+Note that this is not a general defence against compromised clients
+(that is impossible), but it thwarts a simple attack.
+
+NB. due to certain broken SSH implementations aborting upon receipt
+of this message, the no-more-sessions request is only sent to OpenSSH
+servers (identified by banner). Other SSH implementations may be
+whitelisted to receive this message upon request.
+
+2.3. connection: Tunnel forward extension "tun@openssh.com"
+
+OpenSSH supports layer 2 and layer 3 tunnelling via the "tun@openssh.com"
+channel type. This channel type supports forwarding of network packets
+with datagram boundaries intact between endpoints equipped with
+interfaces like the BSD tun(4) device. Tunnel forwarding channels are
+requested by the client with the following packet:
+
+ byte SSH_MSG_CHANNEL_OPEN
+ string "tun@openssh.com"
+ uint32 sender channel
+ uint32 initial window size
+ uint32 maximum packet size
+ uint32 tunnel mode
+ uint32 remote unit number
+
+The "tunnel mode" parameter specifies whether the tunnel should forward
+layer 2 frames or layer 3 packets. It may take one of the following values:
+
+ SSH_TUNMODE_POINTOPOINT 1 /* layer 3 packets */
+ SSH_TUNMODE_ETHERNET 2 /* layer 2 frames */
+
+The "tunnel unit number" specifies the remote interface number, or may
+be 0x7fffffff to allow the server to automatically chose an interface. A
+server that is not willing to open a client-specified unit should refuse
+the request with a SSH_MSG_CHANNEL_OPEN_FAILURE error. On successful
+open, the server should reply with SSH_MSG_CHANNEL_OPEN_SUCCESS.
+
+Once established the client and server may exchange packet or frames
+over the tunnel channel by encapsulating them in SSH protocol strings
+and sending them as channel data. This ensures that packet boundaries
+are kept intact. Specifically, packets are transmitted using normal
+SSH_MSG_CHANNEL_DATA packets:
+
+ byte SSH_MSG_CHANNEL_DATA
+ uint32 recipient channel
+ string data
+
+The contents of the "data" field for layer 3 packets is:
+
+ uint32 packet length
+ uint32 address family
+ byte[packet length - 4] packet data
+
+The "address family" field identifies the type of packet in the message.
+It may be one of:
+
+ SSH_TUN_AF_INET 2 /* IPv4 */
+ SSH_TUN_AF_INET6 24 /* IPv6 */
+
+The "packet data" field consists of the IPv4/IPv6 datagram itself
+without any link layer header.
+
+The contents of the "data" field for layer 2 packets is:
+
+ uint32 packet length
+ byte[packet length] frame
+
+The "frame" field contains an IEEE 802.3 Ethernet frame, including
+header.
+
+2.4. connection: Unix domain socket forwarding
+
+OpenSSH supports local and remote Unix domain socket forwarding
+using the "streamlocal" extension. Forwarding is initiated as per
+TCP sockets but with a single path instead of a host and port.
+
+Similar to direct-tcpip, direct-streamlocal is sent by the client
+to request that the server make a connection to a Unix domain socket.
+
+ byte SSH_MSG_CHANNEL_OPEN
+ string "direct-streamlocal@openssh.com"
+ uint32 sender channel
+ uint32 initial window size
+ uint32 maximum packet size
+ string socket path
+ string reserved
+ uint32 reserved
+
+Similar to forwarded-tcpip, forwarded-streamlocal is sent by the
+server when the client has previously send the server a streamlocal-forward
+GLOBAL_REQUEST.
+
+ byte SSH_MSG_CHANNEL_OPEN
+ string "forwarded-streamlocal@openssh.com"
+ uint32 sender channel
+ uint32 initial window size
+ uint32 maximum packet size
+ string socket path
+ string reserved for future use
+
+The reserved field is not currently defined and is ignored on the
+remote end. It is intended to be used in the future to pass
+information about the socket file, such as ownership and mode.
+The client currently sends the empty string for this field.
+
+Similar to tcpip-forward, streamlocal-forward is sent by the client
+to request remote forwarding of a Unix domain socket.
+
+ byte SSH2_MSG_GLOBAL_REQUEST
+ string "streamlocal-forward@openssh.com"
+ boolean TRUE
+ string socket path
+
+Similar to cancel-tcpip-forward, cancel-streamlocal-forward is sent
+by the client cancel the forwarding of a Unix domain socket.
+
+ byte SSH2_MSG_GLOBAL_REQUEST
+ string "cancel-streamlocal-forward@openssh.com"
+ boolean FALSE
+ string socket path
+
+2.5. connection: hostkey update and rotation "hostkeys-00@openssh.com"
+and "hostkeys-prove-00@openssh.com"
+
+OpenSSH supports a protocol extension allowing a server to inform
+a client of all its protocol v.2 host keys after user-authentication
+has completed.
+
+ byte SSH_MSG_GLOBAL_REQUEST
+ string "hostkeys-00@openssh.com"
+ string[] hostkeys
+
+Upon receiving this message, a client should check which of the
+supplied host keys are present in known_hosts.
+
+Note that the server may send key types that the client does not
+support. The client should disgregard such keys if they are received.
+
+If the client identifies any keys that are not present for the host,
+it should send a "hostkeys-prove@openssh.com" message to request the
+server prove ownership of the private half of the key.
+
+ byte SSH_MSG_GLOBAL_REQUEST
+ string "hostkeys-prove-00@openssh.com"
+ char 1 /* want-reply */
+ string[] hostkeys
+
+When a server receives this message, it should generate a signature
+using each requested key over the following:
+
+ string "hostkeys-prove-00@openssh.com"
+ string session identifier
+ string hostkey
+
+These signatures should be included in the reply, in the order matching
+the hostkeys in the request:
+
+ byte SSH_MSG_REQUEST_SUCCESS
+ string[] signatures
+
+When the client receives this reply (and not a failure), it should
+validate the signatures and may update its known_hosts file, adding keys
+that it has not seen before and deleting keys for the server host that
+are no longer offered.
+
+These extensions let a client learn key types that it had not previously
+encountered, thereby allowing it to potentially upgrade from weaker
+key algorithms to better ones. It also supports graceful key rotation:
+a server may offer multiple keys of the same type for a period (to
+give clients an opportunity to learn them using this extension) before
+removing the deprecated key from those offered.
+
+2.6. connection: SIGINFO support for "signal" channel request
+
+The SSH channels protocol (RFC4254 section 6.9) supports sending a
+signal to a session attached to a channel. OpenSSH supports one
+extension signal "INFO@openssh.com" that allows sending SIGINFO on
+BSD-derived systems.
+
+3. SFTP protocol changes
+
+3.1. sftp: Reversal of arguments to SSH_FXP_SYMLINK
+
+When OpenSSH's sftp-server was implemented, the order of the arguments
+to the SSH_FXP_SYMLINK method was inadvertently reversed. Unfortunately,
+the reversal was not noticed until the server was widely deployed. Since
+fixing this to follow the specification would cause incompatibility, the
+current order was retained. For correct operation, clients should send
+SSH_FXP_SYMLINK as follows:
+
+ uint32 id
+ string targetpath
+ string linkpath
+
+3.2. sftp: Server extension announcement in SSH_FXP_VERSION
+
+OpenSSH's sftp-server lists the extensions it supports using the
+standard extension announcement mechanism in the SSH_FXP_VERSION server
+hello packet:
+
+ uint32 3 /* protocol version */
+ string ext1-name
+ string ext1-version
+ string ext2-name
+ string ext2-version
+ ...
+ string extN-name
+ string extN-version
+
+Each extension reports its integer version number as an ASCII encoded
+string, e.g. "1". The version will be incremented if the extension is
+ever changed in an incompatible way. The server MAY advertise the same
+extension with multiple versions (though this is unlikely). Clients MUST
+check the version number before attempting to use the extension.
+
+3.3. sftp: Extension request "posix-rename@openssh.com"
+
+This operation provides a rename operation with POSIX semantics, which
+are different to those provided by the standard SSH_FXP_RENAME in
+draft-ietf-secsh-filexfer-02.txt. This request is implemented as a
+SSH_FXP_EXTENDED request with the following format:
+
+ uint32 id
+ string "posix-rename@openssh.com"
+ string oldpath
+ string newpath
+
+On receiving this request the server will perform the POSIX operation
+rename(oldpath, newpath) and will respond with a SSH_FXP_STATUS message.
+This extension is advertised in the SSH_FXP_VERSION hello with version
+"1".
+
+3.4. sftp: Extension requests "statvfs@openssh.com" and
+ "fstatvfs@openssh.com"
+
+These requests correspond to the statvfs and fstatvfs POSIX system
+interfaces. The "statvfs@openssh.com" request operates on an explicit
+pathname, and is formatted as follows:
+
+ uint32 id
+ string "statvfs@openssh.com"
+ string path
+
+The "fstatvfs@openssh.com" operates on an open file handle:
+
+ uint32 id
+ string "fstatvfs@openssh.com"
+ string handle
+
+These requests return a SSH_FXP_STATUS reply on failure. On success they
+return the following SSH_FXP_EXTENDED_REPLY reply:
+
+ uint32 id
+ uint64 f_bsize /* file system block size */
+ uint64 f_frsize /* fundamental fs block size */
+ uint64 f_blocks /* number of blocks (unit f_frsize) */
+ uint64 f_bfree /* free blocks in file system */
+ uint64 f_bavail /* free blocks for non-root */
+ uint64 f_files /* total file inodes */
+ uint64 f_ffree /* free file inodes */
+ uint64 f_favail /* free file inodes for to non-root */
+ uint64 f_fsid /* file system id */
+ uint64 f_flag /* bit mask of f_flag values */
+ uint64 f_namemax /* maximum filename length */
+
+The values of the f_flag bitmask are as follows:
+
+ #define SSH_FXE_STATVFS_ST_RDONLY 0x1 /* read-only */
+ #define SSH_FXE_STATVFS_ST_NOSUID 0x2 /* no setuid */
+
+Both the "statvfs@openssh.com" and "fstatvfs@openssh.com" extensions are
+advertised in the SSH_FXP_VERSION hello with version "2".
+
+3.5. sftp: Extension request "hardlink@openssh.com"
+
+This request is for creating a hard link to a regular file. This
+request is implemented as a SSH_FXP_EXTENDED request with the
+following format:
+
+ uint32 id
+ string "hardlink@openssh.com"
+ string oldpath
+ string newpath
+
+On receiving this request the server will perform the operation
+link(oldpath, newpath) and will respond with a SSH_FXP_STATUS message.
+This extension is advertised in the SSH_FXP_VERSION hello with version
+"1".
+
+3.6. sftp: Extension request "fsync@openssh.com"
+
+This request asks the server to call fsync(2) on an open file handle.
+
+ uint32 id
+ string "fsync@openssh.com"
+ string handle
+
+One receiving this request, a server will call fsync(handle_fd) and will
+respond with a SSH_FXP_STATUS message.
+
+This extension is advertised in the SSH_FXP_VERSION hello with version
+"1".
+
+4. Miscellaneous changes
+
+4.1 Public key format
+
+OpenSSH public keys, as generated by ssh-keygen(1) and appearing in
+authorized_keys files, are formatted as a single line of text consisting
+of the public key algorithm name followed by a base64-encoded key blob.
+The public key blob (before base64 encoding) is the same format used for
+the encoding of public keys sent on the wire: as described in RFC4253
+section 6.6 for RSA and DSA keys, RFC5656 section 3.1 for ECDSA keys
+and the "New public key formats" section of PROTOCOL.certkeys for the
+OpenSSH certificate formats.
+
+4.2 Private key format
+
+OpenSSH private keys, as generated by ssh-keygen(1) use the format
+described in PROTOCOL.key by default. As a legacy option, PEM format
+(RFC7468) private keys are also supported for RSA, DSA and ECDSA keys
+and were the default format before OpenSSH 7.8.
+
+4.3 KRL format
+
+OpenSSH supports a compact format for Key Revocation Lists (KRLs). This
+format is described in the PROTOCOL.krl file.
+
+4.4 Connection multiplexing
+
+OpenSSH's connection multiplexing uses messages as described in
+PROTOCOL.mux over a Unix domain socket for communications between a
+master instance and later clients.
+
+$OpenBSD: PROTOCOL,v 1.36 2018/10/02 12:51:58 djm Exp $
diff --git a/PROTOCOL.agent b/PROTOCOL.agent
new file mode 100644
index 0000000..da33819
--- /dev/null
+++ b/PROTOCOL.agent
@@ -0,0 +1,5 @@
+This file used to contain a description of the SSH agent protocol
+implemented by OpenSSH. It has since been superseded by an Internet-
+draft that is available from:
+
+https://tools.ietf.org/html/draft-miller-ssh-agent-02
diff --git a/PROTOCOL.certkeys b/PROTOCOL.certkeys
new file mode 100644
index 0000000..11363fd
--- /dev/null
+++ b/PROTOCOL.certkeys
@@ -0,0 +1,306 @@
+This document describes a simple public-key certificate authentication
+system for use by SSH.
+
+Background
+----------
+
+The SSH protocol currently supports a simple public key authentication
+mechanism. Unlike other public key implementations, SSH eschews the use
+of X.509 certificates and uses raw keys. This approach has some benefits
+relating to simplicity of configuration and minimisation of attack
+surface, but it does not support the important use-cases of centrally
+managed, passwordless authentication and centrally certified host keys.
+
+These protocol extensions build on the simple public key authentication
+system already in SSH to allow certificate-based authentication. The
+certificates used are not traditional X.509 certificates, with numerous
+options and complex encoding rules, but something rather more minimal: a
+key, some identity information and usage options that have been signed
+with some other trusted key.
+
+A sshd server may be configured to allow authentication via certified
+keys, by extending the existing ~/.ssh/authorized_keys mechanism to
+allow specification of certification authority keys in addition to
+raw user keys. The ssh client will support automatic verification of
+acceptance of certified host keys, by adding a similar ability to
+specify CA keys in ~/.ssh/known_hosts.
+
+All certificate types include certification information along with the
+public key that is used to sign challenges. In OpenSSH, ssh-keygen
+performs the CA signing operation.
+
+Certified keys are represented using new key types:
+
+ ssh-rsa-cert-v01@openssh.com
+ ssh-dss-cert-v01@openssh.com
+ ecdsa-sha2-nistp256-cert-v01@openssh.com
+ ecdsa-sha2-nistp384-cert-v01@openssh.com
+ ecdsa-sha2-nistp521-cert-v01@openssh.com
+
+Two additional types exist for RSA certificates to force use of
+SHA-2 signatures (SHA-256 and SHA-512 respectively):
+
+ rsa-sha2-256-cert-v01@openssh.com
+ rsa-sha2-512-cert-v01@openssh.com
+
+These RSA/SHA-2 types should not appear in keys at rest or transmitted
+on their wire, but do appear in a SSH_MSG_KEXINIT's host-key algorithms
+field or in the "public key algorithm name" field of a "publickey"
+SSH_USERAUTH_REQUEST to indicate that the signature will use the
+specified algorithm.
+
+Protocol extensions
+-------------------
+
+The SSH wire protocol includes several extensibility mechanisms.
+These modifications shall take advantage of namespaced public key
+algorithm names to add support for certificate authentication without
+breaking the protocol - implementations that do not support the
+extensions will simply ignore them.
+
+Authentication using the new key formats described below proceeds
+using the existing SSH "publickey" authentication method described
+in RFC4252 section 7.
+
+New public key formats
+----------------------
+
+The certificate key types take a similar high-level format (note: data
+types and encoding are as per RFC4251 section 5). The serialised wire
+encoding of these certificates is also used for storing them on disk.
+
+#define SSH_CERT_TYPE_USER 1
+#define SSH_CERT_TYPE_HOST 2
+
+RSA certificate
+
+ string "ssh-rsa-cert-v01@openssh.com"
+ string nonce
+ mpint e
+ mpint n
+ uint64 serial
+ uint32 type
+ string key id
+ string valid principals
+ uint64 valid after
+ uint64 valid before
+ string critical options
+ string extensions
+ string reserved
+ string signature key
+ string signature
+
+DSA certificate
+
+ string "ssh-dss-cert-v01@openssh.com"
+ string nonce
+ mpint p
+ mpint q
+ mpint g
+ mpint y
+ uint64 serial
+ uint32 type
+ string key id
+ string valid principals
+ uint64 valid after
+ uint64 valid before
+ string critical options
+ string extensions
+ string reserved
+ string signature key
+ string signature
+
+ECDSA certificate
+
+ string "ecdsa-sha2-nistp256-cert-v01@openssh.com" |
+ "ecdsa-sha2-nistp384-cert-v01@openssh.com" |
+ "ecdsa-sha2-nistp521-cert-v01@openssh.com"
+ string nonce
+ string curve
+ string public_key
+ uint64 serial
+ uint32 type
+ string key id
+ string valid principals
+ uint64 valid after
+ uint64 valid before
+ string critical options
+ string extensions
+ string reserved
+ string signature key
+ string signature
+
+ED25519 certificate
+
+ string "ssh-ed25519-cert-v01@openssh.com"
+ string nonce
+ string pk
+ uint64 serial
+ uint32 type
+ string key id
+ string valid principals
+ uint64 valid after
+ uint64 valid before
+ string critical options
+ string extensions
+ string reserved
+ string signature key
+ string signature
+
+The nonce field is a CA-provided random bitstring of arbitrary length
+(but typically 16 or 32 bytes) included to make attacks that depend on
+inducing collisions in the signature hash infeasible.
+
+e and n are the RSA exponent and public modulus respectively.
+
+p, q, g, y are the DSA parameters as described in FIPS-186-2.
+
+curve and public key are respectively the ECDSA "[identifier]" and "Q"
+defined in section 3.1 of RFC5656.
+
+pk is the encoded Ed25519 public key as defined by
+draft-josefsson-eddsa-ed25519-03.
+
+serial is an optional certificate serial number set by the CA to
+provide an abbreviated way to refer to certificates from that CA.
+If a CA does not wish to number its certificates it must set this
+field to zero.
+
+type specifies whether this certificate is for identification of a user
+or a host using a SSH_CERT_TYPE_... value.
+
+key id is a free-form text field that is filled in by the CA at the time
+of signing; the intention is that the contents of this field are used to
+identify the identity principal in log messages.
+
+"valid principals" is a string containing zero or more principals as
+strings packed inside it. These principals list the names for which this
+certificate is valid; hostnames for SSH_CERT_TYPE_HOST certificates and
+usernames for SSH_CERT_TYPE_USER certificates. As a special case, a
+zero-length "valid principals" field means the certificate is valid for
+any principal of the specified type.
+
+"valid after" and "valid before" specify a validity period for the
+certificate. Each represents a time in seconds since 1970-01-01
+00:00:00. A certificate is considered valid if:
+
+ valid after <= current time < valid before
+
+critical options is a set of zero or more key options encoded as
+below. All such options are "critical" in the sense that an implementation
+must refuse to authorise a key that has an unrecognised option.
+
+extensions is a set of zero or more optional extensions. These extensions
+are not critical, and an implementation that encounters one that it does
+not recognise may safely ignore it.
+
+Generally, critical options are used to control features that restrict
+access where extensions are used to enable features that grant access.
+This ensures that certificates containing unknown restrictions do not
+inadvertently grant access while allowing new protocol features to be
+enabled via extensions without breaking certificates' backwards
+compatibility.
+
+The reserved field is currently unused and is ignored in this version of
+the protocol.
+
+The signature key field contains the CA key used to sign the
+certificate. The valid key types for CA keys are ssh-rsa,
+ssh-dss, ssh-ed25519 and the ECDSA types ecdsa-sha2-nistp256,
+ecdsa-sha2-nistp384, ecdsa-sha2-nistp521. "Chained" certificates, where
+the signature key type is a certificate type itself are NOT supported.
+Note that it is possible for a RSA certificate key to be signed by a
+Ed25519 or ECDSA CA key and vice-versa.
+
+signature is computed over all preceding fields from the initial string
+up to, and including the signature key. Signatures are computed and
+encoded according to the rules defined for the CA's public key algorithm
+(RFC4253 section 6.6 for ssh-rsa and ssh-dss, RFC5656 for the ECDSA
+types), and draft-josefsson-eddsa-ed25519-03 for Ed25519.
+
+Critical options
+----------------
+
+The critical options section of the certificate specifies zero or more
+options on the certificates validity. The format of this field
+is a sequence of zero or more tuples:
+
+ string name
+ string data
+
+Options must be lexically ordered by "name" if they appear in the
+sequence. Each named option may only appear once in a certificate.
+
+The name field identifies the option and the data field encodes
+option-specific information (see below). All options are
+"critical", if an implementation does not recognise a option
+then the validating party should refuse to accept the certificate.
+
+Custom options should append the originating author or organisation's
+domain name to the option name, e.g. "my-option@example.com".
+
+No critical options are defined for host certificates at present. The
+supported user certificate options and the contents and structure of
+their data fields are:
+
+Name Format Description
+-----------------------------------------------------------------------------
+force-command string Specifies a command that is executed
+ (replacing any the user specified on the
+ ssh command-line) whenever this key is
+ used for authentication.
+
+source-address string Comma-separated list of source addresses
+ from which this certificate is accepted
+ for authentication. Addresses are
+ specified in CIDR format (nn.nn.nn.nn/nn
+ or hhhh::hhhh/nn).
+ If this option is not present then
+ certificates may be presented from any
+ source address.
+
+Extensions
+----------
+
+The extensions section of the certificate specifies zero or more
+non-critical certificate extensions. The encoding and ordering of
+extensions in this field is identical to that of the critical options,
+as is the requirement that each name appear only once.
+
+If an implementation does not recognise an extension, then it should
+ignore it.
+
+Custom options should append the originating author or organisation's
+domain name to the option name, e.g. "my-option@example.com".
+
+No extensions are defined for host certificates at present. The
+supported user certificate extensions and the contents and structure of
+their data fields are:
+
+Name Format Description
+-----------------------------------------------------------------------------
+permit-X11-forwarding empty Flag indicating that X11 forwarding
+ should be permitted. X11 forwarding will
+ be refused if this option is absent.
+
+permit-agent-forwarding empty Flag indicating that agent forwarding
+ should be allowed. Agent forwarding
+ must not be permitted unless this
+ option is present.
+
+permit-port-forwarding empty Flag indicating that port-forwarding
+ should be allowed. If this option is
+ not present then no port forwarding will
+ be allowed.
+
+permit-pty empty Flag indicating that PTY allocation
+ should be permitted. In the absence of
+ this option PTY allocation will be
+ disabled.
+
+permit-user-rc empty Flag indicating that execution of
+ ~/.ssh/rc should be permitted. Execution
+ of this script will not be permitted if
+ this option is not present.
+
+$OpenBSD: PROTOCOL.certkeys,v 1.15 2018/07/03 11:39:54 djm Exp $
diff --git a/PROTOCOL.chacha20poly1305 b/PROTOCOL.chacha20poly1305
new file mode 100644
index 0000000..9ce2a1e
--- /dev/null
+++ b/PROTOCOL.chacha20poly1305
@@ -0,0 +1,107 @@
+This document describes the chacha20-poly1305@openssh.com authenticated
+encryption cipher supported by OpenSSH.
+
+Background
+----------
+
+ChaCha20 is a stream cipher designed by Daniel Bernstein and described
+in [1]. It operates by permuting 128 fixed bits, 128 or 256 bits of key,
+a 64 bit nonce and a 64 bit counter into 64 bytes of output. This output
+is used as a keystream, with any unused bytes simply discarded.
+
+Poly1305[2], also by Daniel Bernstein, is a one-time Carter-Wegman MAC
+that computes a 128 bit integrity tag given a message and a single-use
+256 bit secret key.
+
+The chacha20-poly1305@openssh.com combines these two primitives into an
+authenticated encryption mode. The construction used is based on that
+proposed for TLS by Adam Langley in [3], but differs in the layout of
+data passed to the MAC and in the addition of encryption of the packet
+lengths.
+
+Negotiation
+-----------
+
+The chacha20-poly1305@openssh.com offers both encryption and
+authentication. As such, no separate MAC is required. If the
+chacha20-poly1305@openssh.com cipher is selected in key exchange,
+the offered MAC algorithms are ignored and no MAC is required to be
+negotiated.
+
+Detailed Construction
+---------------------
+
+The chacha20-poly1305@openssh.com cipher requires 512 bits of key
+material as output from the SSH key exchange. This forms two 256 bit
+keys (K_1 and K_2), used by two separate instances of chacha20.
+The first 256 bits consitute K_2 and the second 256 bits become
+K_1.
+
+The instance keyed by K_1 is a stream cipher that is used only
+to encrypt the 4 byte packet length field. The second instance,
+keyed by K_2, is used in conjunction with poly1305 to build an AEAD
+(Authenticated Encryption with Associated Data) that is used to encrypt
+and authenticate the entire packet.
+
+Two separate cipher instances are used here so as to keep the packet
+lengths confidential but not create an oracle for the packet payload
+cipher by decrypting and using the packet length prior to checking
+the MAC. By using an independently-keyed cipher instance to encrypt the
+length, an active attacker seeking to exploit the packet input handling
+as a decryption oracle can learn nothing about the payload contents or
+its MAC (assuming key derivation, ChaCha20 and Poly1305 are secure).
+
+The AEAD is constructed as follows: for each packet, generate a Poly1305
+key by taking the first 256 bits of ChaCha20 stream output generated
+using K_2, an IV consisting of the packet sequence number encoded as an
+uint64 under the SSH wire encoding rules and a ChaCha20 block counter of
+zero. The K_2 ChaCha20 block counter is then set to the little-endian
+encoding of 1 (i.e. {1, 0, 0, 0, 0, 0, 0, 0}) and this instance is used
+for encryption of the packet payload.
+
+Packet Handling
+---------------
+
+When receiving a packet, the length must be decrypted first. When 4
+bytes of ciphertext length have been received, they may be decrypted
+using the K_1 key, a nonce consisting of the packet sequence number
+encoded as a uint64 under the usual SSH wire encoding and a zero block
+counter to obtain the plaintext length.
+
+Once the entire packet has been received, the MAC MUST be checked
+before decryption. A per-packet Poly1305 key is generated as described
+above and the MAC tag calculated using Poly1305 with this key over the
+ciphertext of the packet length and the payload together. The calculated
+MAC is then compared in constant time with the one appended to the
+packet and the packet decrypted using ChaCha20 as described above (with
+K_2, the packet sequence number as nonce and a starting block counter of
+1).
+
+To send a packet, first encode the 4 byte length and encrypt it using
+K_1. Encrypt the packet payload (using K_2) and append it to the
+encrypted length. Finally, calculate a MAC tag and append it.
+
+Rekeying
+--------
+
+ChaCha20 must never reuse a {key, nonce} for encryption nor may it be
+used to encrypt more than 2^70 bytes under the same {key, nonce}. The
+SSH Transport protocol (RFC4253) recommends a far more conservative
+rekeying every 1GB of data sent or received. If this recommendation
+is followed, then chacha20-poly1305@openssh.com requires no special
+handling in this area.
+
+References
+----------
+
+[1] "ChaCha, a variant of Salsa20", Daniel Bernstein
+ http://cr.yp.to/chacha/chacha-20080128.pdf
+
+[2] "The Poly1305-AES message-authentication code", Daniel Bernstein
+ http://cr.yp.to/mac/poly1305-20050329.pdf
+
+[3] "ChaCha20 and Poly1305 based Cipher Suites for TLS", Adam Langley
+ http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-03
+
+$OpenBSD: PROTOCOL.chacha20poly1305,v 1.4 2018/04/10 00:10:49 djm Exp $
+
diff --git a/PROTOCOL.key b/PROTOCOL.key
new file mode 100644
index 0000000..959bd7a
--- /dev/null
+++ b/PROTOCOL.key
@@ -0,0 +1,68 @@
+This document describes the private key format for OpenSSH.
+
+1. Overall format
+
+The key consists of a header, a list of public keys, and
+an encrypted list of matching private keys.
+
+#define AUTH_MAGIC "openssh-key-v1"
+
+ byte[] AUTH_MAGIC
+ string ciphername
+ string kdfname
+ string kdfoptions
+ int number of keys N
+ string publickey1
+ string publickey2
+ ...
+ string publickeyN
+ string encrypted, padded list of private keys
+
+2. KDF options for kdfname "bcrypt"
+
+The options:
+
+ string salt
+ uint32 rounds
+
+are concatenated and represented as a string.
+
+3. Unencrypted list of N private keys
+
+The list of privatekey/comment pairs is padded with the
+bytes 1, 2, 3, ... until the total length is a multiple
+of the cipher block size.
+
+ uint32 checkint
+ uint32 checkint
+ string privatekey1
+ string comment1
+ string privatekey2
+ string comment2
+ ...
+ string privatekeyN
+ string commentN
+ char 1
+ char 2
+ char 3
+ ...
+ char padlen % 255
+
+Before the key is encrypted, a random integer is assigned
+to both checkint fields so successful decryption can be
+quickly checked by verifying that both checkint fields
+hold the same value.
+
+4. Encryption
+
+The KDF is used to derive a key, IV (and other values required by
+the cipher) from the passphrase. These values are then used to
+encrypt the unencrypted list of private keys.
+
+5. No encryption
+
+For unencrypted keys the cipher "none" and the KDF "none"
+are used with empty passphrases. The options if the KDF "none"
+are the empty string.
+
+$OpenBSD: PROTOCOL.key,v 1.1 2013/12/06 13:34:54 markus Exp $
diff --git a/PROTOCOL.krl b/PROTOCOL.krl
new file mode 100644
index 0000000..115f80e
--- /dev/null
+++ b/PROTOCOL.krl
@@ -0,0 +1,171 @@
+This describes the key/certificate revocation list format for OpenSSH.
+
+1. Overall format
+
+The KRL consists of a header and zero or more sections. The header is:
+
+#define KRL_MAGIC 0x5353484b524c0a00ULL /* "SSHKRL\n\0" */
+#define KRL_FORMAT_VERSION 1
+
+ uint64 KRL_MAGIC
+ uint32 KRL_FORMAT_VERSION
+ uint64 krl_version
+ uint64 generated_date
+ uint64 flags
+ string reserved
+ string comment
+
+Where "krl_version" is a version number that increases each time the KRL
+is modified, "generated_date" is the time in seconds since 1970-01-01
+00:00:00 UTC that the KRL was generated, "comment" is an optional comment
+and "reserved" an extension field whose contents are currently ignored.
+No "flags" are currently defined.
+
+Following the header are zero or more sections, each consisting of:
+
+ byte section_type
+ string section_data
+
+Where "section_type" indicates the type of the "section_data". An exception
+to this is the KRL_SECTION_SIGNATURE section, that has a slightly different
+format (see below).
+
+The available section types are:
+
+#define KRL_SECTION_CERTIFICATES 1
+#define KRL_SECTION_EXPLICIT_KEY 2
+#define KRL_SECTION_FINGERPRINT_SHA1 3
+#define KRL_SECTION_SIGNATURE 4
+#define KRL_SECTION_FINGERPRINT_SHA256 5
+
+2. Certificate section
+
+These sections use type KRL_SECTION_CERTIFICATES to revoke certificates by
+serial number or key ID. The consist of the CA key that issued the
+certificates to be revoked and a reserved field whose contents is currently
+ignored.
+
+ string ca_key
+ string reserved
+
+Where "ca_key" is the standard SSH wire serialisation of the CA's
+public key. Alternately, "ca_key" may be an empty string to indicate
+the certificate section applies to all CAs (this is most useful when
+revoking key IDs).
+
+Followed by one or more sections:
+
+ byte cert_section_type
+ string cert_section_data
+
+The certificate section types are:
+
+#define KRL_SECTION_CERT_SERIAL_LIST 0x20
+#define KRL_SECTION_CERT_SERIAL_RANGE 0x21
+#define KRL_SECTION_CERT_SERIAL_BITMAP 0x22
+#define KRL_SECTION_CERT_KEY_ID 0x23
+
+2.1 Certificate serial list section
+
+This section is identified as KRL_SECTION_CERT_SERIAL_LIST. It revokes
+certificates by listing their serial numbers. The cert_section_data in this
+case contains:
+
+ uint64 revoked_cert_serial
+ uint64 ...
+
+This section may appear multiple times.
+
+2.2. Certificate serial range section
+
+These sections use type KRL_SECTION_CERT_SERIAL_RANGE and hold
+a range of serial numbers of certificates:
+
+ uint64 serial_min
+ uint64 serial_max
+
+All certificates in the range serial_min <= serial <= serial_max are
+revoked.
+
+This section may appear multiple times.
+
+2.3. Certificate serial bitmap section
+
+Bitmap sections use type KRL_SECTION_CERT_SERIAL_BITMAP and revoke keys
+by listing their serial number in a bitmap.
+
+ uint64 serial_offset
+ mpint revoked_keys_bitmap
+
+A bit set at index N in the bitmap corresponds to revocation of a keys with
+serial number (serial_offset + N).
+
+This section may appear multiple times.
+
+2.4. Revoked key ID sections
+
+KRL_SECTION_CERT_KEY_ID sections revoke particular certificate "key
+ID" strings. This may be useful in revoking all certificates
+associated with a particular identity, e.g. a host or a user.
+
+ string key_id[0]
+ ...
+
+This section must contain at least one "key_id". This section may appear
+multiple times.
+
+3. Explicit key sections
+
+These sections, identified as KRL_SECTION_EXPLICIT_KEY, revoke keys
+(not certificates). They are less space efficient than serial numbers,
+but are able to revoke plain keys.
+
+ string public_key_blob[0]
+ ....
+
+This section must contain at least one "public_key_blob". The blob
+must be a raw key (i.e. not a certificate).
+
+This section may appear multiple times.
+
+4. SHA1/SHA256 fingerprint sections
+
+These sections, identified as KRL_SECTION_FINGERPRINT_SHA1 and
+KRL_SECTION_FINGERPRINT_SHA256, revoke plain keys (i.e. not
+certificates) by listing their hashes:
+
+ string public_key_hash[0]
+ ....
+
+This section must contain at least one "public_key_hash". The hash blob
+is obtained by taking the SHA1 or SHA256 hash of the public key blob.
+Hashes in this section must appear in numeric order, treating each hash
+as a big-endian integer.
+
+This section may appear multiple times.
+
+5. KRL signature sections
+
+The KRL_SECTION_SIGNATURE section serves a different purpose to the
+preceding ones: to provide cryptographic authentication of a KRL that
+is retrieved over a channel that does not provide integrity protection.
+Its format is slightly different to the previously-described sections:
+in order to simplify the signature generation, it includes as a "body"
+two string components instead of one.
+
+ byte KRL_SECTION_SIGNATURE
+ string signature_key
+ string signature
+
+The signature is calculated over the entire KRL from the KRL_MAGIC
+to this subsection's "signature_key", including both and using the
+signature generation rules appropriate for the type of "signature_key".
+
+This section must appear last in the KRL. If multiple signature sections
+appear, they must appear consecutively at the end of the KRL file.
+
+Implementations that retrieve KRLs over untrusted channels must verify
+signatures. Signature sections are optional for KRLs distributed by
+trusted means.
+
+$OpenBSD: PROTOCOL.krl,v 1.5 2018/09/12 01:21:34 djm Exp $
diff --git a/PROTOCOL.mux b/PROTOCOL.mux
new file mode 100644
index 0000000..77a0780
--- /dev/null
+++ b/PROTOCOL.mux
@@ -0,0 +1,298 @@
+This document describes the multiplexing protocol used by ssh(1)'s
+ControlMaster connection-sharing.
+
+Multiplexing starts with a ssh(1) configured to act as a multiplexing
+master. This will cause ssh(1) to listen on a Unix domain socket for
+requests from clients. Clients communicate over this socket using a
+simple packetised protocol, where each message is proceeded with
+a length and message type in SSH uint32 wire format:
+
+ uint32 packet length
+ uint32 packet type
+ ... packet body
+
+Most messages from the client to the server contain a "request id"
+field. This field is returned in replies as "client request id" to
+facilitate matching of responses to requests.
+
+Many muliplexing (mux) client requests yield immediate responses from
+the mux process; requesting a forwarding, performing an alive check or
+requesting the master terminate itself fall in to this category.
+
+The most common use of multiplexing however is to maintain multiple
+concurrent sessions. These are supported via two separate modes:
+
+"Passenger" clients start by requesting a new session with a
+MUX_C_NEW_SESSION message and passing stdio file descriptors over the
+Unix domain control socket. The passenger client then waits until it is
+signaled or the mux server closes the session. This mode is so named as
+the client waits around while the mux server does all the driving.
+
+Stdio forwarding (requested using MUX_C_NEW_STDIO_FWD) is another
+example of passenger mode; the client passes the stdio file descriptors
+and passively waits for something to happen.
+
+"Proxy" clients, requested using MUX_C_PROXY, work quite differently. In
+this mode, the mux client/server connection socket will stop speaking
+the multiplexing protocol and start proxying SSH connection protocol
+messages between the client and server. The client therefore must
+speak a significant subset of the SSH protocol, but in return is able
+to access basically the full suite of connection protocol features.
+Moreover, as no file descriptor passing is required, the connection
+supporting a proxy client may iteself be forwarded or relayed to another
+host if necessary.
+
+1. Connection setup
+
+When a multiplexing connection is made to a ssh(1) operating as a
+ControlMaster from a client ssh(1), the first action of each is send
+a hello messages to its peer:
+
+ uint32 MUX_MSG_HELLO
+ uint32 protocol version
+ string extension name [optional]
+ string extension value [optional]
+ ...
+
+The current version of the mux protocol is 4. A client should refuse
+to connect to a master that speaks an unsupported protocol version.
+
+Following the version identifier are zero or more extensions represented
+as a name/value pair. No extensions are currently defined.
+
+2. Opening a passenger mode session
+
+To open a new multiplexed session in passenger mode, a client sends the
+following request:
+
+ uint32 MUX_C_NEW_SESSION
+ uint32 request id
+ string reserved
+ bool want tty flag
+ bool want X11 forwarding flag
+ bool want agent flag
+ bool subsystem flag
+ uint32 escape char
+ string terminal type
+ string command
+ string environment string 0 [optional]
+ ...
+
+To disable the use of an escape character, "escape char" may be set
+to 0xffffffff. "terminal type" is generally set to the value of
+$TERM. zero or more environment strings may follow the command.
+
+The client then sends its standard input, output and error file
+descriptors (in that order) using Unix domain socket control messages.
+
+The contents of "reserved" are currently ignored.
+
+If successful, the server will reply with MUX_S_SESSION_OPENED
+
+ uint32 MUX_S_SESSION_OPENED
+ uint32 client request id
+ uint32 session id
+
+Otherwise it will reply with an error: MUX_S_PERMISSION_DENIED or
+MUX_S_FAILURE.
+
+Once the server has received the fds, it will respond with MUX_S_OK
+indicating that the session is up. The client now waits for the
+session to end. When it does, the server will send an exit status
+message:
+
+ uint32 MUX_S_EXIT_MESSAGE
+ uint32 session id
+ uint32 exit value
+
+The client should exit with this value to mimic the behaviour of a
+non-multiplexed ssh(1) connection. Two additional cases that the
+client must cope with are it receiving a signal itself and the
+server disconnecting without sending an exit message.
+
+A master may also send a MUX_S_TTY_ALLOC_FAIL before MUX_S_EXIT_MESSAGE
+if remote TTY allocation was unsuccessful. The client may use this to
+return its local tty to "cooked" mode.
+
+ uint32 MUX_S_TTY_ALLOC_FAIL
+ uint32 session id
+
+3. Requesting passenger-mode stdio forwarding
+
+A client may request the master to establish a stdio forwarding:
+
+ uint32 MUX_C_NEW_STDIO_FWD
+ uint32 request id
+ string reserved
+ string connect host
+ string connect port
+
+The client then sends its standard input and output file descriptors
+(in that order) using Unix domain socket control messages.
+
+The contents of "reserved" are currently ignored.
+
+A server may reply with a MUX_S_SESSION_OPENED, a MUX_S_PERMISSION_DENIED
+or a MUX_S_FAILURE.
+
+4. Health checks
+
+The client may request a health check/PID report from a server:
+
+ uint32 MUX_C_ALIVE_CHECK
+ uint32 request id
+
+The server replies with:
+
+ uint32 MUX_S_ALIVE
+ uint32 client request id
+ uint32 server pid
+
+5. Remotely terminating a master
+
+A client may request that a master terminate immediately:
+
+ uint32 MUX_C_TERMINATE
+ uint32 request id
+
+The server will reply with one of MUX_S_OK or MUX_S_PERMISSION_DENIED.
+
+6. Requesting establishment of port forwards
+
+A client may request the master to establish a port forward:
+
+ uint32 MUX_C_OPEN_FWD
+ uint32 request id
+ uint32 forwarding type
+ string listen host
+ uint32 listen port
+ string connect host
+ uint32 connect port
+
+forwarding type may be MUX_FWD_LOCAL, MUX_FWD_REMOTE, MUX_FWD_DYNAMIC.
+
+If listen port is (unsigned int) -2, then the listen host is treated as
+a unix socket path name.
+
+If connect port is (unsigned int) -2, then the connect host is treated
+as a unix socket path name.
+
+A server may reply with a MUX_S_OK, a MUX_S_REMOTE_PORT, a
+MUX_S_PERMISSION_DENIED or a MUX_S_FAILURE.
+
+For dynamically allocated listen port the server replies with
+
+ uint32 MUX_S_REMOTE_PORT
+ uint32 client request id
+ uint32 allocated remote listen port
+
+7. Requesting closure of port forwards
+
+Note: currently unimplemented (server will always reply with MUX_S_FAILURE).
+
+A client may request the master to close a port forward:
+
+ uint32 MUX_C_CLOSE_FWD
+ uint32 request id
+ uint32 forwarding type
+ string listen host
+ uint32 listen port
+ string connect host
+ uint32 connect port
+
+A server may reply with a MUX_S_OK, a MUX_S_PERMISSION_DENIED or a
+MUX_S_FAILURE.
+
+8. Requesting shutdown of mux listener
+
+A client may request the master to stop accepting new multiplexing requests
+and remove its listener socket.
+
+ uint32 MUX_C_STOP_LISTENING
+ uint32 request id
+
+A server may reply with a MUX_S_OK, a MUX_S_PERMISSION_DENIED or a
+MUX_S_FAILURE.
+
+9. Requesting proxy mode
+
+A client may request that the the control connection be placed in proxy
+mode:
+
+ uint32 MUX_C_PROXY
+ uint32 request id
+
+When a mux master receives this message, it will reply with a
+confirmation:
+
+ uint32 MUX_S_PROXY
+ uint32 request id
+
+And go into proxy mode. All subsequent data over the connection will
+be formatted as unencrypted, unpadded, SSH transport messages:
+
+ uint32 packet length
+ byte 0 (padding length)
+ byte packet type
+ byte[packet length - 2] ...
+
+The mux master will accept most connection messages and global requests,
+and will translate channel identifiers to ensure that the proxy client has
+globally unique channel numbers (i.e. a proxy client need not worry about
+collisions with other clients).
+
+10. Status messages
+
+The MUX_S_OK message is empty:
+
+ uint32 MUX_S_OK
+ uint32 client request id
+
+The MUX_S_PERMISSION_DENIED and MUX_S_FAILURE include a reason:
+
+ uint32 MUX_S_PERMISSION_DENIED
+ uint32 client request id
+ string reason
+
+ uint32 MUX_S_FAILURE
+ uint32 client request id
+ string reason
+
+11. Protocol numbers
+
+#define MUX_MSG_HELLO 0x00000001
+#define MUX_C_NEW_SESSION 0x10000002
+#define MUX_C_ALIVE_CHECK 0x10000004
+#define MUX_C_TERMINATE 0x10000005
+#define MUX_C_OPEN_FWD 0x10000006
+#define MUX_C_CLOSE_FWD 0x10000007
+#define MUX_C_NEW_STDIO_FWD 0x10000008
+#define MUX_C_STOP_LISTENING 0x10000009
+#define MUX_S_OK 0x80000001
+#define MUX_S_PERMISSION_DENIED 0x80000002
+#define MUX_S_FAILURE 0x80000003
+#define MUX_S_EXIT_MESSAGE 0x80000004
+#define MUX_S_ALIVE 0x80000005
+#define MUX_S_SESSION_OPENED 0x80000006
+#define MUX_S_REMOTE_PORT 0x80000007
+#define MUX_S_TTY_ALLOC_FAIL 0x80000008
+
+#define MUX_FWD_LOCAL 1
+#define MUX_FWD_REMOTE 2
+#define MUX_FWD_DYNAMIC 3
+
+XXX TODO
+XXX extended status (e.g. report open channels / forwards)
+XXX lock (maybe)
+XXX watch in/out traffic (pre/post crypto)
+XXX inject packet (what about replies)
+XXX server->client error/warning notifications
+XXX send signals via mux
+XXX ^Z support in passengers
+XXX extensions for multi-agent
+XXX extensions for multi-X11
+XXX session inspection via master
+XXX signals via mux request
+XXX list active connections via mux
+
+$OpenBSD: PROTOCOL.mux,v 1.11 2018/09/26 07:30:05 djm Exp $