Damien Miller | b401f92 | 2010-02-10 10:17:49 +1100 | [diff] [blame] | 1 | This document describes the multiplexing protocol used by ssh(1)'s |
| 2 | ControlMaster connection-sharing. |
| 3 | |
| 4 | Most messages from the client to the server contain a "request id" field. |
| 5 | This field is returned in replies as "client request id" to facilitate |
| 6 | matching of responses to requests. |
| 7 | |
| 8 | 1. Connection setup |
| 9 | |
| 10 | When a multiplexing connection is made to a ssh(1) operating as a |
| 11 | ControlMaster from a ssh(1) in multiplex slave mode, the first |
| 12 | action of each is to exchange hello messages: |
| 13 | |
| 14 | uint32 MUX_MSG_HELLO |
| 15 | uint32 protocol version |
| 16 | string extension name [optional] |
| 17 | string extension value [optional] |
| 18 | ... |
| 19 | |
| 20 | The current version of the mux protocol is 4. A slave should refuse |
| 21 | to connect to a master that speaks an unsupported protocol version. |
| 22 | Following the version identifier are zero or more extensions |
| 23 | represented as a name/value pair. No extensions are currently |
| 24 | defined. |
| 25 | |
| 26 | 2. Opening sessions |
| 27 | |
| 28 | To open a new multiplexed session, a client may send the following |
| 29 | request: |
| 30 | |
Damien Miller | 42747df | 2011-01-14 12:01:50 +1100 | [diff] [blame] | 31 | uint32 MUX_C_NEW_SESSION |
Damien Miller | b401f92 | 2010-02-10 10:17:49 +1100 | [diff] [blame] | 32 | uint32 request id |
| 33 | string reserved |
| 34 | bool want tty flag |
| 35 | bool want X11 forwarding flag |
| 36 | bool want agent flag |
| 37 | bool subsystem flag |
| 38 | uint32 escape char |
| 39 | string terminal type |
| 40 | string command |
| 41 | string environment string 0 [optional] |
| 42 | ... |
| 43 | |
| 44 | To disable the use of an escape character, "escape char" may be set |
| 45 | to 0xffffffff. "terminal type" is generally set to the value of |
| 46 | $TERM. zero or more environment strings may follow the command. |
| 47 | |
| 48 | The client then sends its standard input, output and error file |
| 49 | descriptors (in that order) using Unix domain socket control messages. |
| 50 | |
| 51 | The contents of "reserved" are currently ignored. |
| 52 | |
| 53 | If successful, the server will reply with MUX_S_SESSION_OPENED |
| 54 | |
| 55 | uint32 MUX_S_SESSION_OPENED |
| 56 | uint32 client request id |
| 57 | uint32 session id |
| 58 | |
| 59 | Otherwise it will reply with an error: MUX_S_PERMISSION_DENIED or |
| 60 | MUX_S_FAILURE. |
| 61 | |
| 62 | Once the server has received the fds, it will respond with MUX_S_OK |
| 63 | indicating that the session is up. The client now waits for the |
| 64 | session to end. When it does, the server will send an exit status |
| 65 | message: |
| 66 | |
| 67 | uint32 MUX_S_EXIT_MESSAGE |
| 68 | uint32 session id |
| 69 | uint32 exit value |
| 70 | |
| 71 | The client should exit with this value to mimic the behaviour of a |
| 72 | non-multiplexed ssh(1) connection. Two additional cases that the |
| 73 | client must cope with are it receiving a signal itself and the |
| 74 | server disconnecting without sending an exit message. |
| 75 | |
Damien Miller | 555f3b8 | 2011-05-15 08:48:05 +1000 | [diff] [blame] | 76 | A master may also send a MUX_S_TTY_ALLOC_FAIL before MUX_S_EXIT_MESSAGE |
| 77 | if remote TTY allocation was unsuccessful. The client may use this to |
| 78 | return its local tty to "cooked" mode. |
| 79 | |
| 80 | uint32 MUX_S_TTY_ALLOC_FAIL |
| 81 | uint32 session id |
| 82 | |
Damien Miller | b401f92 | 2010-02-10 10:17:49 +1100 | [diff] [blame] | 83 | 3. Health checks |
| 84 | |
| 85 | The client may request a health check/PID report from a server: |
| 86 | |
| 87 | uint32 MUX_C_ALIVE_CHECK |
| 88 | uint32 request id |
| 89 | |
| 90 | The server replies with: |
| 91 | |
| 92 | uint32 MUX_S_ALIVE |
| 93 | uint32 client request id |
| 94 | uint32 server pid |
| 95 | |
| 96 | 4. Remotely terminating a master |
| 97 | |
| 98 | A client may request that a master terminate immediately: |
| 99 | |
| 100 | uint32 MUX_C_TERMINATE |
| 101 | uint32 request id |
| 102 | |
| 103 | The server will reply with one of MUX_S_OK or MUX_S_PERMISSION_DENIED. |
| 104 | |
| 105 | 5. Requesting establishment of port forwards |
| 106 | |
| 107 | A client may request the master to establish a port forward: |
| 108 | |
Damien Miller | 42747df | 2011-01-14 12:01:50 +1100 | [diff] [blame] | 109 | uint32 MUX_C_OPEN_FWD |
Damien Miller | b401f92 | 2010-02-10 10:17:49 +1100 | [diff] [blame] | 110 | uint32 request id |
| 111 | uint32 forwarding type |
| 112 | string listen host |
Damien Miller | 7f12157 | 2012-06-20 21:51:29 +1000 | [diff] [blame] | 113 | uint32 listen port |
Damien Miller | b401f92 | 2010-02-10 10:17:49 +1100 | [diff] [blame] | 114 | string connect host |
Damien Miller | 7f12157 | 2012-06-20 21:51:29 +1000 | [diff] [blame] | 115 | uint32 connect port |
Damien Miller | b401f92 | 2010-02-10 10:17:49 +1100 | [diff] [blame] | 116 | |
| 117 | forwarding type may be MUX_FWD_LOCAL, MUX_FWD_REMOTE, MUX_FWD_DYNAMIC. |
| 118 | |
djm@openbsd.org | 356b61f | 2015-07-17 03:04:27 +0000 | [diff] [blame] | 119 | If listen port is (unsigned int) -2, then the listen host is treated as |
| 120 | a unix socket path name. |
| 121 | |
| 122 | If connect port is (unsigned int) -2, then the connect host is treated |
| 123 | as a unix socket path name. |
| 124 | |
Damien Miller | 388f6fc | 2010-05-21 14:57:35 +1000 | [diff] [blame] | 125 | A server may reply with a MUX_S_OK, a MUX_S_REMOTE_PORT, a |
| 126 | MUX_S_PERMISSION_DENIED or a MUX_S_FAILURE. |
| 127 | |
| 128 | For dynamically allocated listen port the server replies with |
| 129 | |
| 130 | uint32 MUX_S_REMOTE_PORT |
| 131 | uint32 client request id |
| 132 | uint32 allocated remote listen port |
Damien Miller | b401f92 | 2010-02-10 10:17:49 +1100 | [diff] [blame] | 133 | |
Damien Miller | 42747df | 2011-01-14 12:01:50 +1100 | [diff] [blame] | 134 | 6. Requesting closure of port forwards |
| 135 | |
| 136 | Note: currently unimplemented (server will always reply with MUX_S_FAILURE). |
Damien Miller | b401f92 | 2010-02-10 10:17:49 +1100 | [diff] [blame] | 137 | |
Damien Miller | b407dd8 | 2011-02-04 11:46:39 +1100 | [diff] [blame] | 138 | A client may request the master to close a port forward: |
Damien Miller | b401f92 | 2010-02-10 10:17:49 +1100 | [diff] [blame] | 139 | |
Damien Miller | 42747df | 2011-01-14 12:01:50 +1100 | [diff] [blame] | 140 | uint32 MUX_C_CLOSE_FWD |
Damien Miller | b401f92 | 2010-02-10 10:17:49 +1100 | [diff] [blame] | 141 | uint32 request id |
Damien Miller | 4cb855b | 2011-09-22 21:37:38 +1000 | [diff] [blame] | 142 | uint32 forwarding type |
Damien Miller | b401f92 | 2010-02-10 10:17:49 +1100 | [diff] [blame] | 143 | string listen host |
Damien Miller | 7f12157 | 2012-06-20 21:51:29 +1000 | [diff] [blame] | 144 | uint32 listen port |
Damien Miller | b401f92 | 2010-02-10 10:17:49 +1100 | [diff] [blame] | 145 | string connect host |
Damien Miller | 7f12157 | 2012-06-20 21:51:29 +1000 | [diff] [blame] | 146 | uint32 connect port |
Damien Miller | b401f92 | 2010-02-10 10:17:49 +1100 | [diff] [blame] | 147 | |
Damien Miller | b401f92 | 2010-02-10 10:17:49 +1100 | [diff] [blame] | 148 | A server may reply with a MUX_S_OK, a MUX_S_PERMISSION_DENIED or a |
| 149 | MUX_S_FAILURE. |
| 150 | |
Damien Miller | 42747df | 2011-01-14 12:01:50 +1100 | [diff] [blame] | 151 | 7. Requesting stdio forwarding |
Damien Miller | b401f92 | 2010-02-10 10:17:49 +1100 | [diff] [blame] | 152 | |
| 153 | A client may request the master to establish a stdio forwarding: |
| 154 | |
| 155 | uint32 MUX_C_NEW_STDIO_FWD |
| 156 | uint32 request id |
| 157 | string reserved |
| 158 | string connect host |
| 159 | string connect port |
| 160 | |
| 161 | The client then sends its standard input and output file descriptors |
| 162 | (in that order) using Unix domain socket control messages. |
| 163 | |
| 164 | The contents of "reserved" are currently ignored. |
| 165 | |
Damien Miller | 6c3eec7 | 2011-05-05 14:16:22 +1000 | [diff] [blame] | 166 | A server may reply with a MUX_S_SESSION_OPENED, a MUX_S_PERMISSION_DENIED |
Damien Miller | b401f92 | 2010-02-10 10:17:49 +1100 | [diff] [blame] | 167 | or a MUX_S_FAILURE. |
| 168 | |
Damien Miller | 6c3eec7 | 2011-05-05 14:16:22 +1000 | [diff] [blame] | 169 | 8. Requesting shutdown of mux listener |
| 170 | |
| 171 | A client may request the master to stop accepting new multiplexing requests |
| 172 | and remove its listener socket. |
| 173 | |
| 174 | uint32 MUX_C_STOP_LISTENING |
| 175 | uint32 request id |
| 176 | |
| 177 | A server may reply with a MUX_S_OK, a MUX_S_PERMISSION_DENIED or a |
| 178 | MUX_S_FAILURE. |
| 179 | |
| 180 | 9. Status messages |
Damien Miller | b401f92 | 2010-02-10 10:17:49 +1100 | [diff] [blame] | 181 | |
| 182 | The MUX_S_OK message is empty: |
| 183 | |
| 184 | uint32 MUX_S_OK |
| 185 | uint32 client request id |
| 186 | |
| 187 | The MUX_S_PERMISSION_DENIED and MUX_S_FAILURE include a reason: |
| 188 | |
| 189 | uint32 MUX_S_PERMISSION_DENIED |
| 190 | uint32 client request id |
| 191 | string reason |
| 192 | |
| 193 | uint32 MUX_S_FAILURE |
| 194 | uint32 client request id |
| 195 | string reason |
| 196 | |
Damien Miller | c067f62 | 2011-05-15 08:46:54 +1000 | [diff] [blame] | 197 | 10. Protocol numbers |
Damien Miller | b401f92 | 2010-02-10 10:17:49 +1100 | [diff] [blame] | 198 | |
| 199 | #define MUX_MSG_HELLO 0x00000001 |
| 200 | #define MUX_C_NEW_SESSION 0x10000002 |
| 201 | #define MUX_C_ALIVE_CHECK 0x10000004 |
| 202 | #define MUX_C_TERMINATE 0x10000005 |
Damien Miller | 42747df | 2011-01-14 12:01:50 +1100 | [diff] [blame] | 203 | #define MUX_C_OPEN_FWD 0x10000006 |
| 204 | #define MUX_C_CLOSE_FWD 0x10000007 |
| 205 | #define MUX_C_NEW_STDIO_FWD 0x10000008 |
Damien Miller | 6c3eec7 | 2011-05-05 14:16:22 +1000 | [diff] [blame] | 206 | #define MUX_C_STOP_LISTENING 0x10000009 |
Damien Miller | b401f92 | 2010-02-10 10:17:49 +1100 | [diff] [blame] | 207 | #define MUX_S_OK 0x80000001 |
| 208 | #define MUX_S_PERMISSION_DENIED 0x80000002 |
| 209 | #define MUX_S_FAILURE 0x80000003 |
| 210 | #define MUX_S_EXIT_MESSAGE 0x80000004 |
| 211 | #define MUX_S_ALIVE 0x80000005 |
| 212 | #define MUX_S_SESSION_OPENED 0x80000006 |
Damien Miller | 388f6fc | 2010-05-21 14:57:35 +1000 | [diff] [blame] | 213 | #define MUX_S_REMOTE_PORT 0x80000007 |
Damien Miller | 555f3b8 | 2011-05-15 08:48:05 +1000 | [diff] [blame] | 214 | #define MUX_S_TTY_ALLOC_FAIL 0x80000008 |
Damien Miller | b401f92 | 2010-02-10 10:17:49 +1100 | [diff] [blame] | 215 | |
| 216 | #define MUX_FWD_LOCAL 1 |
| 217 | #define MUX_FWD_REMOTE 2 |
| 218 | #define MUX_FWD_DYNAMIC 3 |
| 219 | |
| 220 | XXX TODO |
| 221 | XXX extended status (e.g. report open channels / forwards) |
Damien Miller | b401f92 | 2010-02-10 10:17:49 +1100 | [diff] [blame] | 222 | XXX lock (maybe) |
| 223 | XXX watch in/out traffic (pre/post crypto) |
| 224 | XXX inject packet (what about replies) |
| 225 | XXX server->client error/warning notifications |
Damien Miller | b401f92 | 2010-02-10 10:17:49 +1100 | [diff] [blame] | 226 | XXX send signals via mux |
| 227 | |
djm@openbsd.org | 356b61f | 2015-07-17 03:04:27 +0000 | [diff] [blame] | 228 | $OpenBSD: PROTOCOL.mux,v 1.10 2015/07/17 03:04:27 djm Exp $ |