PROTOCOL revision 295367
1292934SdimThis documents OpenSSH's deviations and extensions to the published SSH
2292934Sdimprotocol.
3353358Sdim
4353358SdimNote that OpenSSH's sftp and sftp-server implement revision 3 of the SSH
5353358Sdimfilexfer protocol described in:
6292934Sdim
7292934Sdimhttp://www.openssh.com/txt/draft-ietf-secsh-filexfer-02.txt
8292934Sdim
9292934SdimNewer versions of the draft will not be supported, though some features
10292934Sdimare individually implemented as extensions described below.
11292934Sdim
12292934SdimThe protocol used by OpenSSH's ssh-agent is described in the file
13292934SdimPROTOCOL.agent
14292934Sdim
15292934Sdim1. Transport protocol changes
16292934Sdim
17292934Sdim1.1. transport: Protocol 2 MAC algorithm "umac-64@openssh.com"
18327952Sdim
19327952SdimThis is a new transport-layer MAC method using the UMAC algorithm
20292934Sdim(rfc4418). This method is identical to the "umac-64" method documented
21292934Sdimin:
22321369Sdim
23292934Sdimhttp://www.openssh.com/txt/draft-miller-secsh-umac-01.txt
24321369Sdim
25292934Sdim1.2. transport: Protocol 2 compression algorithm "zlib@openssh.com"
26292934Sdim
27292934SdimThis transport-layer compression method uses the zlib compression
28292934Sdimalgorithm (identical to the "zlib" method in rfc4253), but delays the
29292934Sdimstart of compression until after authentication has completed. This
30321369Sdimavoids exposing compression code to attacks from unauthenticated users.
31292934Sdim
32292934SdimThe method is documented in:
33292934Sdim
34327952Sdimhttp://www.openssh.com/txt/draft-miller-secsh-compression-delayed-00.txt
35292934Sdim
36292934Sdim1.3. transport: New public key algorithms "ssh-rsa-cert-v00@openssh.com",
37292934Sdim     "ssh-dsa-cert-v00@openssh.com",
38292934Sdim     "ecdsa-sha2-nistp256-cert-v01@openssh.com",
39292934Sdim     "ecdsa-sha2-nistp384-cert-v01@openssh.com" and
40292934Sdim     "ecdsa-sha2-nistp521-cert-v01@openssh.com"
41292934Sdim
42292934SdimOpenSSH introduces new public key algorithms to support certificate
43292934Sdimauthentication for users and host keys. These methods are documented
44292934Sdimin the file PROTOCOL.certkeys
45321369Sdim
46321369Sdim1.4. transport: Elliptic Curve cryptography
47321369Sdim
48292934SdimOpenSSH supports ECC key exchange and public key authentication as
49292934Sdimspecified in RFC5656. Only the ecdsa-sha2-nistp256, ecdsa-sha2-nistp384
50353358Sdimand ecdsa-sha2-nistp521 curves over GF(p) are supported. Elliptic
51353358Sdimcurve points encoded using point compression are NOT accepted or
52353358Sdimgenerated.
53353358Sdim
54353358Sdim1.5 transport: Protocol 2 Encrypt-then-MAC MAC algorithms
55292934Sdim
56292934SdimOpenSSH supports MAC algorithms, whose names contain "-etm", that
57353358Sdimperform the calculations in a different order to that defined in RFC
58353358Sdim4253. These variants use the so-called "encrypt then MAC" ordering,
59353358Sdimcalculating the MAC over the packet ciphertext rather than the
60353358Sdimplaintext. This ordering closes a security flaw in the SSH transport
61353358Sdimprotocol, where decryption of unauthenticated ciphertext provided a
62321369Sdim"decryption oracle" that could, in conjunction with cipher flaws, reveal
63353358Sdimsession plaintext.
64321369Sdim
65353358SdimSpecifically, the "-etm" MAC algorithms modify the transport protocol
66292934Sdimto calculate the MAC over the packet ciphertext and to send the packet
67292934Sdimlength unencrypted. This is necessary for the transport to obtain the
68292934Sdimlength of the packet and location of the MAC tag so that it may be
69353358Sdimverified without decrypting unauthenticated data.
70353358Sdim
71292934SdimAs such, the MAC covers:
72292934Sdim
73292934Sdim      mac = MAC(key, sequence_number || packet_length || encrypted_packet)
74292934Sdim
75292934Sdimwhere "packet_length" is encoded as a uint32 and "encrypted_packet"
76353358Sdimcontains:
77353358Sdim
78353358Sdim      byte      padding_length
79353358Sdim      byte[n1]  payload; n1 = packet_length - padding_length - 1
80353358Sdim      byte[n2]  random padding; n2 = padding_length
81353358Sdim
82353358Sdim1.6 transport: AES-GCM
83292934Sdim
84292934SdimOpenSSH supports the AES-GCM algorithm as specified in RFC 5647.
85292934SdimBecause of problems with the specification of the key exchange
86292934Sdimthe behaviour of OpenSSH differs from the RFC as follows:
87353358Sdim
88353358SdimAES-GCM is only negotiated as the cipher algorithms
89353358Sdim"aes128-gcm@openssh.com" or "aes256-gcm@openssh.com" and never as
90353358Sdiman MAC algorithm. Additionally, if AES-GCM is selected as the cipher
91353358Sdimthe exchanged MAC algorithms are ignored and there doesn't have to be
92353358Sdima matching MAC.
93353358Sdim
94353358Sdim1.7 transport: chacha20-poly1305@openssh.com authenticated encryption
95292934Sdim
96292934SdimOpenSSH supports authenticated encryption using ChaCha20 and Poly1305
97353358Sdimas described in PROTOCOL.chacha20poly1305.
98353358Sdim
99353358Sdim1.8 transport: curve25519-sha256@libssh.org key exchange algorithm
100353358Sdim
101353358SdimOpenSSH supports the use of ECDH in Curve25519 for key exchange as
102353358Sdimdescribed at:
103353358Sdimhttp://git.libssh.org/users/aris/libssh.git/plain/doc/curve25519-sha256@libssh.org.txt?h=curve25519
104353358Sdim
105353358Sdim2. Connection protocol changes
106353358Sdim
107341825Sdim2.1. connection: Channel write close extension "eow@openssh.com"
108353358Sdim
109341825SdimThe SSH connection protocol (rfc4254) provides the SSH_MSG_CHANNEL_EOF
110341825Sdimmessage to allow an endpoint to signal its peer that it will send no
111341825Sdimmore data over a channel. Unfortunately, there is no symmetric way for
112292934Sdiman endpoint to request that its peer should cease sending data to it
113353358Sdimwhile still keeping the channel open for the endpoint to send data to
114353358Sdimthe peer.
115353358Sdim
116353358SdimThis is desirable, since it saves the transmission of data that would
117353358Sdimotherwise need to be discarded and it allows an endpoint to signal local
118353358Sdimprocesses of the condition, e.g. by closing the corresponding file
119292934Sdimdescriptor.
120292934Sdim
121353358SdimOpenSSH implements a channel extension message to perform this
122292934Sdimsignalling: "eow@openssh.com" (End Of Write). This message is sent by
123292934Sdiman endpoint when the local output of a session channel is closed or
124292934Sdimexperiences a write error. The message is formatted as follows:
125292934Sdim
126292934Sdim	byte		SSH_MSG_CHANNEL_REQUEST
127292934Sdim	uint32		recipient channel
128292934Sdim	string		"eow@openssh.com"
129292934Sdim	boolean		FALSE
130353358Sdim
131353358SdimOn receiving this message, the peer SHOULD cease sending data of
132353358Sdimthe channel and MAY signal the process from which the channel data
133353358Sdimoriginates (e.g. by closing its read file descriptor).
134292934Sdim
135292934SdimAs with the symmetric SSH_MSG_CHANNEL_EOF message, the channel does
136292934Sdimremain open after a "eow@openssh.com" has been sent and more data may
137292934Sdimstill be sent in the other direction. This message does not consume
138353358Sdimwindow space and may be sent even if no window space is available.
139353358Sdim
140353358SdimNB. due to certain broken SSH implementations aborting upon receipt
141353358Sdimof this message (in contravention of RFC4254 section 5.4), this
142353358Sdimmessage is only sent to OpenSSH peers (identified by banner).
143353358SdimOther SSH implementations may be whitelisted to receive this message
144353358Sdimupon request.
145353358Sdim
146353358Sdim2.2. connection: disallow additional sessions extension
147292934Sdim     "no-more-sessions@openssh.com"
148292934Sdim
149292934SdimMost SSH connections will only ever request a single session, but a
150292934Sdimattacker may abuse a running ssh client to surreptitiously open
151353358Sdimadditional sessions under their control. OpenSSH provides a global
152353358Sdimrequest "no-more-sessions@openssh.com" to mitigate this attack.
153353358Sdim
154353358SdimWhen an OpenSSH client expects that it will never open another session
155353358Sdim(i.e. it has been started with connection multiplexing disabled), it
156353358Sdimwill send the following global request:
157341825Sdim
158353358Sdim	byte		SSH_MSG_GLOBAL_REQUEST
159341825Sdim	string		"no-more-sessions@openssh.com"
160353358Sdim	char		want-reply
161353358Sdim
162353358SdimOn receipt of such a message, an OpenSSH server will refuse to open
163353358Sdimfuture channels of type "session" and instead immediately abort the
164353358Sdimconnection.
165353358Sdim
166292934SdimNote that this is not a general defence against compromised clients
167292934Sdim(that is impossible), but it thwarts a simple attack.
168292934Sdim
169353358SdimNB. due to certain broken SSH implementations aborting upon receipt
170353358Sdimof this message, the no-more-sessions request is only sent to OpenSSH
171353358Sdimservers (identified by banner). Other SSH implementations may be
172353358Sdimwhitelisted to receive this message upon request.
173303239Sdim
174353358Sdim2.3. connection: Tunnel forward extension "tun@openssh.com"
175303239Sdim
176303239SdimOpenSSH supports layer 2 and layer 3 tunnelling via the "tun@openssh.com"
177353358Sdimchannel type. This channel type supports forwarding of network packets
178303239Sdimwith datagram boundaries intact between endpoints equipped with
179303239Sdiminterfaces like the BSD tun(4) device. Tunnel forwarding channels are
180353358Sdimrequested by the client with the following packet:
181303239Sdim
182303239Sdim	byte		SSH_MSG_CHANNEL_OPEN
183353358Sdim	string		"tun@openssh.com"
184303239Sdim	uint32		sender channel
185303239Sdim	uint32		initial window size
186353358Sdim	uint32		maximum packet size
187303239Sdim	uint32		tunnel mode
188303239Sdim	uint32		remote unit number
189353358Sdim
190303239SdimThe "tunnel mode" parameter specifies whether the tunnel should forward
191303239Sdimlayer 2 frames or layer 3 packets. It may take one of the following values:
192353358Sdim
193303239Sdim	SSH_TUNMODE_POINTOPOINT  1		/* layer 3 packets */
194303239Sdim	SSH_TUNMODE_ETHERNET     2		/* layer 2 frames */
195353358Sdim
196303239SdimThe "tunnel unit number" specifies the remote interface number, or may
197303239Sdimbe 0x7fffffff to allow the server to automatically chose an interface. A
198353358Sdimserver that is not willing to open a client-specified unit should refuse
199303239Sdimthe request with a SSH_MSG_CHANNEL_OPEN_FAILURE error. On successful
200303239Sdimopen, the server should reply with SSH_MSG_CHANNEL_OPEN_SUCCESS.
201303239Sdim
202353358SdimOnce established the client and server may exchange packet or frames
203353358Sdimover the tunnel channel by encapsulating them in SSH protocol strings
204353358Sdimand sending them as channel data. This ensures that packet boundaries
205353358Sdimare kept intact. Specifically, packets are transmitted using normal
206353358SdimSSH_MSG_CHANNEL_DATA packets:
207353358Sdim
208303239Sdim	byte		SSH_MSG_CHANNEL_DATA
209303239Sdim	uint32		recipient channel
210327952Sdim	string		data
211353358Sdim
212353358SdimThe contents of the "data" field for layer 3 packets is:
213353358Sdim
214353358Sdim	uint32			packet length
215353358Sdim	uint32			address family
216327952Sdim	byte[packet length - 4]	packet data
217327952Sdim
218353358SdimThe "address family" field identifies the type of packet in the message.
219353358SdimIt may be one of:
220353358Sdim
221327952Sdim	SSH_TUN_AF_INET		2		/* IPv4 */
222327952Sdim	SSH_TUN_AF_INET6	24		/* IPv6 */
223353358Sdim
224327952SdimThe "packet data" field consists of the IPv4/IPv6 datagram itself
225327952Sdimwithout any link layer header.
226353358Sdim
227353358SdimThe contents of the "data" field for layer 2 packets is:
228353358Sdim
229353358Sdim	uint32			packet length
230353358Sdim	byte[packet length]	frame
231353358Sdim
232353358SdimThe "frame" field contains an IEEE 802.3 Ethernet frame, including
233353358Sdimheader.
234353358Sdim
235353358Sdim2.4. connection: Unix domain socket forwarding
236353358Sdim
237353358SdimOpenSSH supports local and remote Unix domain socket forwarding
238353358Sdimusing the "streamlocal" extension.  Forwarding is initiated as per
239353358SdimTCP sockets but with a single path instead of a host and port.
240353358Sdim
241353358SdimSimilar to direct-tcpip, direct-streamlocal is sent by the client
242353358Sdimto request that the server make a connection to a Unix domain socket.
243353358Sdim
244353358Sdim	byte		SSH_MSG_CHANNEL_OPEN
245353358Sdim	string		"direct-streamlocal@openssh.com"
246353358Sdim	uint32		sender channel
247292934Sdim	uint32		initial window size
248292934Sdim	uint32		maximum packet size
249353358Sdim	string		socket path
250353358Sdim
251353358SdimSimilar to forwarded-tcpip, forwarded-streamlocal is sent by the
252292934Sdimserver when the client has previously send the server a streamlocal-forward
253292934SdimGLOBAL_REQUEST.
254353358Sdim
255353358Sdim	byte		SSH_MSG_CHANNEL_OPEN
256353358Sdim	string		"forwarded-streamlocal@openssh.com"
257353358Sdim	uint32		sender channel
258353358Sdim	uint32		initial window size
259292934Sdim	uint32		maximum packet size
260353358Sdim	string		socket path
261353358Sdim	string		reserved for future use
262353358Sdim
263353358SdimThe reserved field is not currently defined and is ignored on the
264353358Sdimremote end.  It is intended to be used in the future to pass
265292934Sdiminformation about the socket file, such as ownership and mode.
266292934SdimThe client currently sends the empty string for this field.
267292934Sdim
268292934SdimSimilar to tcpip-forward, streamlocal-forward is sent by the client
269353358Sdimto request remote forwarding of a Unix domain socket.
270353358Sdim
271353358Sdim	byte		SSH2_MSG_GLOBAL_REQUEST
272292934Sdim	string		"streamlocal-forward@openssh.com"
273292934Sdim	boolean		TRUE
274292934Sdim	string		socket path
275353358Sdim
276353358SdimSimilar to cancel-tcpip-forward, cancel-streamlocal-forward is sent
277292934Sdimby the client cancel the forwarding of a Unix domain socket.
278353358Sdim
279353358Sdim	byte		SSH2_MSG_GLOBAL_REQUEST
280353358Sdim	string		"cancel-streamlocal-forward@openssh.com"
281292934Sdim	boolean		FALSE
282292934Sdim	string		socket path
283353358Sdim
284353358Sdim2.5. connection: hostkey update and rotation "hostkeys-00@openssh.com"
285353358Sdimand "hostkeys-prove-00@openssh.com"
286292934Sdim
287292934SdimOpenSSH supports a protocol extension allowing a server to inform
288353358Sdima client of all its protocol v.2 host keys after user-authentication
289292934Sdimhas completed.
290292934Sdim
291292934Sdim	byte		SSH_MSG_GLOBAL_REQUEST
292353358Sdim	string		"hostkeys-00@openssh.com"
293353358Sdim	string[]	hostkeys
294353358Sdim
295353358SdimUpon receiving this message, a client should check which of the
296353358Sdimsupplied host keys are present in known_hosts. For keys that are
297353358Sdimnot present, it should send a "hostkeys-prove@openssh.com" message
298353358Sdimto request the server prove ownership of the private half of the
299353358Sdimkey.
300353358Sdim
301353358Sdim	byte		SSH_MSG_GLOBAL_REQUEST
302353358Sdim	string		"hostkeys-prove-00@openssh.com"
303353358Sdim	char		1 /* want-reply */
304353358Sdim	string[]	hostkeys
305353358Sdim
306353358SdimWhen a server receives this message, it should generate a signature
307353358Sdimusing each requested key over the following:
308353358Sdim
309353358Sdim	string		"hostkeys-prove-00@openssh.com"
310353358Sdim	string		session identifier
311353358Sdim	string		hostkey
312353358Sdim
313314564SdimThese signatures should be included in the reply, in the order matching
314314564Sdimthe hostkeys in the request:
315314564Sdim
316314564Sdim	byte		SSH_MSG_REQUEST_SUCCESS
317353358Sdim	string[]	signatures
318353358Sdim
319353358SdimWhen the client receives this reply (and not a failure), it should
320353358Sdimvalidate the signatures and may update its known_hosts file, adding keys
321353358Sdimthat it has not seen before and deleting keys for the server host that
322321369Sdimare no longer offered.
323353358Sdim
324353358SdimThese extensions let a client learn key types that it had not previously
325360784Sdimencountered, thereby allowing it to potentially upgrade from weaker
326353358Sdimkey algorithms to better ones. It also supports graceful key rotation:
327353358Sdima server may offer multiple keys of the same type for a period (to
328353358Sdimgive clients an opportunity to learn them using this extension) before
329321369Sdimremoving the deprecated key from those offered.
330314564Sdim
331314564Sdim3. SFTP protocol changes
332353358Sdim
333353358Sdim3.1. sftp: Reversal of arguments to SSH_FXP_SYMLINK
334314564Sdim
335314564SdimWhen OpenSSH's sftp-server was implemented, the order of the arguments
336314564Sdimto the SSH_FXP_SYMLINK method was inadvertently reversed. Unfortunately,
337353358Sdimthe reversal was not noticed until the server was widely deployed. Since
338314564Sdimfixing this to follow the specification would cause incompatibility, the
339353358Sdimcurrent order was retained. For correct operation, clients should send
340353358SdimSSH_FXP_SYMLINK as follows:
341314564Sdim
342314564Sdim	uint32		id
343314564Sdim	string		targetpath
344314564Sdim	string		linkpath
345314564Sdim
346314564Sdim3.2. sftp: Server extension announcement in SSH_FXP_VERSION
347314564Sdim
348353358SdimOpenSSH's sftp-server lists the extensions it supports using the
349353358Sdimstandard extension announcement mechanism in the SSH_FXP_VERSION server
350314564Sdimhello packet:
351353358Sdim
352353358Sdim	uint32		3		/* protocol version */
353314564Sdim	string		ext1-name
354314564Sdim	string		ext1-version
355353358Sdim	string		ext2-name
356314564Sdim	string		ext2-version
357314564Sdim	...
358314564Sdim	string		extN-name
359327952Sdim	string		extN-version
360353358Sdim
361353358SdimEach extension reports its integer version number as an ASCII encoded
362303239Sdimstring, e.g. "1". The version will be incremented if the extension is
363292934Sdimever changed in an incompatible way. The server MAY advertise the same
364292934Sdimextension with multiple versions (though this is unlikely). Clients MUST
365353358Sdimcheck the version number before attempting to use the extension.
366292934Sdim
367292934Sdim3.3. sftp: Extension request "posix-rename@openssh.com"
368353358Sdim
369353358SdimThis operation provides a rename operation with POSIX semantics, which
370292934Sdimare different to those provided by the standard SSH_FXP_RENAME in
371292934Sdimdraft-ietf-secsh-filexfer-02.txt. This request is implemented as a
372353358SdimSSH_FXP_EXTENDED request with the following format:
373353358Sdim
374292934Sdim	uint32		id
375292934Sdim	string		"posix-rename@openssh.com"
376292934Sdim	string		oldpath
377292934Sdim	string		newpath
378353358Sdim
379353358SdimOn receiving this request the server will perform the POSIX operation
380327952Sdimrename(oldpath, newpath) and will respond with a SSH_FXP_STATUS message.
381353358SdimThis extension is advertised in the SSH_FXP_VERSION hello with version
382327952Sdim"1".
383327952Sdim
384327952Sdim3.4. sftp: Extension requests "statvfs@openssh.com" and
385353358Sdim         "fstatvfs@openssh.com"
386353358Sdim
387292934SdimThese requests correspond to the statvfs and fstatvfs POSIX system
388292934Sdiminterfaces. The "statvfs@openssh.com" request operates on an explicit
389353358Sdimpathname, and is formatted as follows:
390353358Sdim
391353358Sdim	uint32		id
392327952Sdim	string		"statvfs@openssh.com"
393353358Sdim	string		path
394353358Sdim
395327952SdimThe "fstatvfs@openssh.com" operates on an open file handle:
396353358Sdim
397327952Sdim	uint32		id
398353358Sdim	string		"fstatvfs@openssh.com"
399353358Sdim	string		handle
400353358Sdim
401353358SdimThese requests return a SSH_FXP_STATUS reply on failure. On success they
402353358Sdimreturn the following SSH_FXP_EXTENDED_REPLY reply:
403353358Sdim
404327952Sdim	uint32		id
405327952Sdim	uint64		f_bsize		/* file system block size */
406353358Sdim	uint64		f_frsize	/* fundamental fs block size */
407303239Sdim	uint64		f_blocks	/* number of blocks (unit f_frsize) */
408303239Sdim	uint64		f_bfree		/* free blocks in file system */
409353358Sdim	uint64		f_bavail	/* free blocks for non-root */
410327952Sdim	uint64		f_files		/* total file inodes */
411327952Sdim	uint64		f_ffree		/* free file inodes */
412353358Sdim	uint64		f_favail	/* free file inodes for to non-root */
413360784Sdim	uint64		f_fsid		/* file system id */
414353358Sdim	uint64		f_flag		/* bit mask of f_flag values */
415353358Sdim	uint64		f_namemax	/* maximum filename length */
416353358Sdim
417353358SdimThe values of the f_flag bitmask are as follows:
418303239Sdim
419327952Sdim	#define SSH_FXE_STATVFS_ST_RDONLY	0x1	/* read-only */
420327952Sdim	#define SSH_FXE_STATVFS_ST_NOSUID	0x2	/* no setuid */
421353358Sdim
422303239SdimBoth the "statvfs@openssh.com" and "fstatvfs@openssh.com" extensions are
423353358Sdimadvertised in the SSH_FXP_VERSION hello with version "2".
424353358Sdim
425353358Sdim10. sftp: Extension request "hardlink@openssh.com"
426353358Sdim
427353358SdimThis request is for creating a hard link to a regular file. This
428353358Sdimrequest is implemented as a SSH_FXP_EXTENDED request with the
429303239Sdimfollowing format:
430353358Sdim
431353358Sdim	uint32		id
432353358Sdim	string		"hardlink@openssh.com"
433327952Sdim	string		oldpath
434353358Sdim	string		newpath
435327952Sdim
436327952SdimOn receiving this request the server will perform the operation
437303239Sdimlink(oldpath, newpath) and will respond with a SSH_FXP_STATUS message.
438303239SdimThis extension is advertised in the SSH_FXP_VERSION hello with version
439327952Sdim"1".
440353358Sdim
441353358Sdim10. sftp: Extension request "fsync@openssh.com"
442353358Sdim
443327952SdimThis request asks the server to call fsync(2) on an open file handle.
444327952Sdim
445353358Sdim	uint32		id
446327952Sdim	string		"fsync@openssh.com"
447353358Sdim	string		handle
448327952Sdim
449327952SdimOne receiving this request, a server will call fsync(handle_fd) and will
450341825Sdimrespond with a SSH_FXP_STATUS message.
451353358Sdim
452353358SdimThis extension is advertised in the SSH_FXP_VERSION hello with version
453321369Sdim"1".
454321369Sdim
455353358Sdim$OpenBSD: PROTOCOL,v 1.29 2015/07/17 03:09:19 djm Exp $
456321369Sdim