1 | <?xml version="1.0"?> |
---|
2 | <!DOCTYPE rfc SYSTEM "rfc2629.dtd"> |
---|
3 | <?rfc private="remctl Protocol" toc="yes" symrefs="yes"?> |
---|
4 | <rfc> |
---|
5 | <front> |
---|
6 | <title abbrev="remctl">remctl: Remote Authenticated Command Service</title> |
---|
7 | <author initials='R.' surname='Allbery' fullname='Russ Allbery'> |
---|
8 | <organization>Stanford University</organization> |
---|
9 | <address> |
---|
10 | <postal> |
---|
11 | <street>255 Panama Street, MC 4136</street> |
---|
12 | <city>Stanford</city> <region>CA</region> |
---|
13 | <code>94305-4136</code> <country>US</country> |
---|
14 | </postal> |
---|
15 | <email>rra@stanford.edu</email> |
---|
16 | <uri>http://www.eyrie.org/~eagle/</uri> |
---|
17 | </address> |
---|
18 | </author> |
---|
19 | <date month='September' year='2007' /> |
---|
20 | |
---|
21 | <abstract> |
---|
22 | <t>This document specifies the remctl wire protocol, used to send |
---|
23 | commands and arguments to a remote system and receive the results of |
---|
24 | executing that command. The protocol uses GSS-API and Kerberos v5 |
---|
25 | for authentication, confidentiality, and integrity protection. Both |
---|
26 | the current (version 2) protocol and the older version 1 protocol |
---|
27 | are described. The version 1 protocol should only be implemented |
---|
28 | for backward compatibility.</t> |
---|
29 | </abstract> |
---|
30 | </front> |
---|
31 | |
---|
32 | <middle> |
---|
33 | <section anchor='format' title='Basic Packet Format'> |
---|
34 | <t>The remctl network protocol consists of data packets sent from a |
---|
35 | client to a server or a server to a client over a TCP connection. |
---|
36 | The remctl protocol may be used over any port, but the |
---|
37 | IANA-registered port and the RECOMMENDED default for the protocol is |
---|
38 | 4373. Each data packet has the following format:</t> |
---|
39 | |
---|
40 | <figure> |
---|
41 | <artwork> |
---|
42 | 1 octet flags |
---|
43 | 4 octets length |
---|
44 | <length> data payload |
---|
45 | </artwork> |
---|
46 | </figure> |
---|
47 | |
---|
48 | <t>The total size of each token, including the five octet prefix, |
---|
49 | MUST NOT be larger than 1,048,576 octets (1MB).</t> |
---|
50 | |
---|
51 | <figure> |
---|
52 | <preamble>The flag octet contains one or more of the following |
---|
53 | values, combined with binary xor:</preamble> |
---|
54 | |
---|
55 | <artwork> |
---|
56 | 0x01 TOKEN_NOOP |
---|
57 | 0x02 TOKEN_CONTEXT |
---|
58 | 0x04 TOKEN_DATA |
---|
59 | 0x08 TOKEN_MIC |
---|
60 | 0x10 TOKEN_CONTEXT_NEXT |
---|
61 | 0x20 TOKEN_SEND_MIC |
---|
62 | 0x40 TOKEN_PROTOCOL |
---|
63 | </artwork> |
---|
64 | |
---|
65 | <postamble>Only TOKEN_CONTEXT, TOKEN_CONTEXT_NEXT, TOKEN_DATA, and |
---|
66 | TOKEN_PROTOCOL are used for version 2 packets. The other flags |
---|
67 | are used only with the legacy version 1 protocol.</postamble> |
---|
68 | </figure> |
---|
69 | |
---|
70 | <t>The length field is a four-octet length in network byte order, |
---|
71 | specifying the number of octets in the following data payload.</t> |
---|
72 | |
---|
73 | <t>The data payload is empty, the results of gss_accept_sec_context, |
---|
74 | the results of gss_init_sec_context, or a data payload protected |
---|
75 | with gss_wrap. The length of the data passed to gss_wrap MUST NOT |
---|
76 | be larger than 65,536 octets (64KB), even if the underlying Kerberos |
---|
77 | implementation supports longer input buffers.</t> |
---|
78 | </section> |
---|
79 | |
---|
80 | <section anchor='proto2' title='Network Protocol (version 2)'> |
---|
81 | <section anchor='packet' title='Session Sequence'> |
---|
82 | <t>A remctl connection is always initiated by a client opening a |
---|
83 | TCP connection to a server. The protocol then proceeds as |
---|
84 | follows: |
---|
85 | <list style='numbers'> |
---|
86 | <t>Client sends message with an empty payload and flags |
---|
87 | TOKEN_NOOP, TOKEN_CONTEXT_NEXT, and TOKEN_PROTOCOL (0x51). If |
---|
88 | the client doesn't include TOKEN_PROTOCOL, it is speaking the |
---|
89 | version 1 protocol, and the server MUST either drop the |
---|
90 | connection or fall back to the version 1 protocol. This |
---|
91 | initial message is useless in a pure version 2 protocol world |
---|
92 | and is done only for backward compatibility with the version 1 |
---|
93 | protocol.</t> |
---|
94 | |
---|
95 | <t>Client calls gss_init_sec_context and replies with the |
---|
96 | results and TOKEN_CONTEXT and TOKEN_PROTOCOL (0x42). The |
---|
97 | client MUST pass GSS_C_MUTUAL_FLAG, GSS_C_CONF_FLAG, and |
---|
98 | GSS_C_INTEG_FLAG as requested flags and SHOULD pass |
---|
99 | GSS_C_REPLAY_FLAG and GSS_C_SEQUENCE_FLAG.</t> |
---|
100 | |
---|
101 | <t>Server replies with the results of gss_accept_sec_context |
---|
102 | and flags TOKEN_CONTEXT and TOKEN_PROTOCOL (0x42). If the |
---|
103 | server doesn't include TOKEN_PROTOCOL in the flags, it is |
---|
104 | speaking the version 1 protocol, and the client MUST either |
---|
105 | drop the connection or fall back to the version 1 |
---|
106 | protocol.</t> |
---|
107 | |
---|
108 | <t>Client passes data to gss_init_sec_context and replies with |
---|
109 | the results and TOKEN_CONTEXT and TOKEN_PROTOCOL (0x42). The |
---|
110 | client must pass GSS_C_MUTUAL_FLAG, GSS_C_CONF_FLAG, and |
---|
111 | GSS_C_INTEG_FLAG as requested flags and SHOULD pass |
---|
112 | GSS_C_REPLAY_FLAG and GSS_C_SEQUENCE_FLAG.</t> |
---|
113 | |
---|
114 | <t>Server and client repeat, passing in the payload from the |
---|
115 | last packet from the other side, for as long as GSS-API |
---|
116 | indicates that continuation is required. If either side drops |
---|
117 | TOKEN_PROTOCOL from the flags, it is an considered an error |
---|
118 | and the connect MUST be dropped. (This could be a |
---|
119 | down-negotiation attack.) After the establishment of the |
---|
120 | security context, both client and server MUST confirm that |
---|
121 | GSS_C_MUTUAL_FLAG, GSS_C_CONF_FLAG, and GSS_C_INTEG_FLAG are |
---|
122 | set in the resulting security context and MUST immediately |
---|
123 | close the connection if this is not the case.</t> |
---|
124 | |
---|
125 | <t>After the security context has been established, the client |
---|
126 | and server exchange commands and responses as described below. |
---|
127 | All commands are sent with flags TOKEN_DATA and TOKEN_PROTOCOL |
---|
128 | (0x44) and the data payload of all packets is protected with |
---|
129 | gss_wrap. The conf_req_flag parameter of gss_wrap MUST be set |
---|
130 | to non-zero, requesting both confidentiality and integrity |
---|
131 | services.</t> |
---|
132 | </list> |
---|
133 | </t> |
---|
134 | </section> |
---|
135 | |
---|
136 | <section anchor='messages' title='Message Format'> |
---|
137 | <t>All client and server messages will use the following format |
---|
138 | inside the data payload. This is the format of the message before |
---|
139 | passing it to gss_wrap for confidentiality and integrity |
---|
140 | protection.</t> |
---|
141 | |
---|
142 | <figure> |
---|
143 | <artwork> |
---|
144 | 1 octet protocol version |
---|
145 | 1 octet message type |
---|
146 | <command-specific data> |
---|
147 | </artwork> |
---|
148 | </figure> |
---|
149 | |
---|
150 | <t>The protocol version for the version 2 protocol is 2. (Note |
---|
151 | that the version 1 protocol does not use this message format, and |
---|
152 | therefore a protocol version of 1 is invalid.) See below for |
---|
153 | protocol version negotiation.</t> |
---|
154 | |
---|
155 | <figure> |
---|
156 | <preamble>The message type is one of the following |
---|
157 | constants:</preamble> |
---|
158 | |
---|
159 | <artwork> |
---|
160 | 1 MESSAGE_COMMAND |
---|
161 | 2 MESSAGE_QUIT |
---|
162 | 3 MESSAGE_OUTPUT |
---|
163 | 4 MESSAGE_STATUS |
---|
164 | 5 MESSAGE_ERROR |
---|
165 | 6 MESSAGE_VERSION |
---|
166 | </artwork> |
---|
167 | </figure> |
---|
168 | |
---|
169 | <t>The first two message types are client messages and MUST NOT be |
---|
170 | sent by the server. The remaining message types are server messages |
---|
171 | and MUST NOT by sent by the client.</t> |
---|
172 | </section> |
---|
173 | |
---|
174 | <section anchor='negotiation' title='Protocol Version Negotiation'> |
---|
175 | <t>If the server ever receives a message from a client that claims a |
---|
176 | protocol version higher than the server supports, the server MUST |
---|
177 | otherwise ignore the contents of the message and SHOULD respond with |
---|
178 | a message type of MESSAGE_VERSION and the following message |
---|
179 | payload:</t> |
---|
180 | |
---|
181 | <figure> |
---|
182 | <artwork> |
---|
183 | 1 octet highest supported version |
---|
184 | </artwork> |
---|
185 | </figure> |
---|
186 | |
---|
187 | <t>The client MUST then either send only messages supported at |
---|
188 | that protocol version or lower or send MESSAGE_QUIT and close the |
---|
189 | connection.</t> |
---|
190 | </section> |
---|
191 | |
---|
192 | <section anchor='command' title='MESSAGE_COMMAND'> |
---|
193 | <t>Most client messages will be of type MESSAGE_COMMAND, which has |
---|
194 | the following format:</t> |
---|
195 | |
---|
196 | <figure> |
---|
197 | <artwork> |
---|
198 | 1 octet keep-alive flag |
---|
199 | 1 octet continue status |
---|
200 | 4 octets number of arguments |
---|
201 | 4 octets argument length |
---|
202 | <length> argument |
---|
203 | ... |
---|
204 | </artwork> |
---|
205 | </figure> |
---|
206 | |
---|
207 | <t>If the keep-alive flag is 0, the server SHOULD close the |
---|
208 | connection after processing the command. If it is 1, the server |
---|
209 | SHOULD leave the connection open (up to a timeout period) and wait |
---|
210 | for more commands. This is similar to HTTP keep-alive.</t> |
---|
211 | |
---|
212 | <t>If the continue status is 1, it indicates that there is more |
---|
213 | data coming. The server should accept the data sent, buffer or |
---|
214 | process it, and wait for more data before responding. If the the |
---|
215 | continue status is 2, it indicates that this message is logically |
---|
216 | a part of the previous message (which MUST have had a continue |
---|
217 | status of 1 or 2) and still has more data coming. If the continue |
---|
218 | status is 3, it says that this message is logically part of the |
---|
219 | previous message, like 2, but it also says that this is the end of |
---|
220 | the command.</t> |
---|
221 | |
---|
222 | <t>A continuation of a message starts with the keep-alive flag and |
---|
223 | continue status and then the next chunk of data. To reconstruct a |
---|
224 | continued message, remove the first two octets from each chunk and |
---|
225 | concatenate the pieces together. The result is the portion of a |
---|
226 | MESSAGE_COMMAND starting with the number of arguments. Messages |
---|
227 | may be broken into multiple MESSAGE_COMMANDs even in the middle of |
---|
228 | the number of arguments or an argument length. In other words, |
---|
229 | the first three octets of the number of arguments could be in the |
---|
230 | first MESSAGE_COMMAND (with continue status 1) and the last octet |
---|
231 | would then be in the next MESSAGE_COMMAND (with continue status 2 |
---|
232 | or 3).</t> |
---|
233 | |
---|
234 | <t>Number of arguments is a four-octet number in network byte |
---|
235 | order that gives the total number of command arguments. For each |
---|
236 | argument, there is then a length and argument data pair, where the |
---|
237 | length is a four-octet number in network byte order indicating the |
---|
238 | number of octets of data in the following argument. Argument |
---|
239 | length may be 0. Commands with no arguments are permitted by the |
---|
240 | protocol.</t> |
---|
241 | |
---|
242 | <t>Servers may impose limits on the number of arguments and the |
---|
243 | size of argument data to limit resource usage. If the client |
---|
244 | message exceeds one of those limits, the server MUST respond with |
---|
245 | MESSAGE_ERROR with an error code of ERROR_TOOMANY_ARGS or |
---|
246 | ERROR_TOOMUCH_DATA as appropriate.</t> |
---|
247 | </section> |
---|
248 | |
---|
249 | <section anchor='output' title='MESSAGE_OUTPUT and MESSAGE_STATUS'> |
---|
250 | <t>The server response to MESSAGE_COMMAND is zero or more |
---|
251 | MESSAGE_OUTPUT messages followed by either a MESSAGE_STATUS or a |
---|
252 | MESSAGE_ERROR response. Each MESSAGE_OUTPUT message has the |
---|
253 | following format:</t> |
---|
254 | |
---|
255 | <figure> |
---|
256 | <artwork> |
---|
257 | 1 octet output stream |
---|
258 | 4 octets output length |
---|
259 | <length> output |
---|
260 | </artwork> |
---|
261 | </figure> |
---|
262 | |
---|
263 | <t>The output stream is either 1 for standard output or 2 for |
---|
264 | standard error. Output length is a four-octet number in network |
---|
265 | byte order that specifies the length of the following output |
---|
266 | data.</t> |
---|
267 | |
---|
268 | <t>The MESSAGE_STATUS message has the following format:</t> |
---|
269 | |
---|
270 | <figure> |
---|
271 | <artwork> |
---|
272 | 1 octet exit status |
---|
273 | </artwork> |
---|
274 | </figure> |
---|
275 | |
---|
276 | <t>MESSAGE_STATUS indicates the command has finished and returns |
---|
277 | the final exit stauts of the command. Exit status is 0 for |
---|
278 | success and non-zero for failure, where the meaning of non-zero |
---|
279 | exit statuses is left to the application to define. (This is |
---|
280 | identical to a Unix command exit status.)</t> |
---|
281 | |
---|
282 | <t>Unless the MESSAGE_COMMAND message from the client had the |
---|
283 | keep-alive flag set to 1, the server MUST close the network |
---|
284 | connection immediately after sending the MESSAGE_STATUS response |
---|
285 | message.</t> |
---|
286 | </section> |
---|
287 | |
---|
288 | <section anchor='error' title='MESSAGE_ERROR'> |
---|
289 | <t>At any point before sending MESSAGE_STATUS, the server may |
---|
290 | respond with MESSAGE_ERROR if some error occurred. This can be |
---|
291 | the first response after a MESSAGE_COMMAND, or it may be sent |
---|
292 | after one or more MESSAGE_OUTPUT messages. The format of |
---|
293 | MESSAGE_ERROR is as follows:</t> |
---|
294 | |
---|
295 | <figure> |
---|
296 | <artwork> |
---|
297 | 4 octets error code |
---|
298 | 4 octets message length |
---|
299 | <length> error message |
---|
300 | </artwork> |
---|
301 | </figure> |
---|
302 | |
---|
303 | <t>The error code is a four-octet number in network byte order |
---|
304 | indicating the type of error. The error code may be one of the |
---|
305 | following values:</t> |
---|
306 | |
---|
307 | <figure> |
---|
308 | <artwork> |
---|
309 | 1 ERROR_INTERNAL Internal server failure |
---|
310 | 2 ERROR_BAD_TOKEN Invalid format in token |
---|
311 | 3 ERROR_UNKNOWN_MESSAGE Unknown message type |
---|
312 | 4 ERROR_BAD_COMMAND Invalid command format in token |
---|
313 | 5 ERROR_UNKNOWN_COMMAND Unknown command |
---|
314 | 6 ERROR_ACCESS Access denied |
---|
315 | 7 ERROR_TOOMANY_ARGS Argument count exceeds server limit |
---|
316 | 8 ERROR_TOOMUCH_DATA Argument size exceeds server limit |
---|
317 | </artwork> |
---|
318 | </figure> |
---|
319 | |
---|
320 | <t>Additional error codes may be added without changing the |
---|
321 | version of the remctl protocol, so clients MUST accept error codes |
---|
322 | other than the ones above.</t> |
---|
323 | |
---|
324 | <t>The message length is a four-octet number in network byte order |
---|
325 | that specifies the length in octets of the following error |
---|
326 | message. The error message is a free-form informational message |
---|
327 | intended for human consumption and MUST NOT be interpreted by an |
---|
328 | automated process. Software should instead use the error |
---|
329 | code.</t> |
---|
330 | |
---|
331 | <t>Unless the MESSAGE_COMMAND message from the client had the |
---|
332 | keep-alive flag set to 1, the server MUST close the network |
---|
333 | connection immediately after sending the MESSAGE_ERROR response |
---|
334 | message. Otherwise, the server SHOULD still honor that flag, |
---|
335 | although the server MAY terminate the connection after an |
---|
336 | unreasonable number of errors.</t> |
---|
337 | </section> |
---|
338 | |
---|
339 | <section anchor='quit' title='MESSAGE_QUIT'> |
---|
340 | <t>MESSAGE_QUIT is a way of terminating the connection cleanly if |
---|
341 | the client asked for keep-alive and then decided not to use it. |
---|
342 | There is no message body. Upon receiving this message, the server |
---|
343 | MUST immediately close the connection.</t> |
---|
344 | </section> |
---|
345 | </section> |
---|
346 | |
---|
347 | <section anchor='proto1' title='Network Protocol (version 1)'> |
---|
348 | <t>The old network protocol supported only 64KB of data payload, |
---|
349 | only a single command and response, and had some additional |
---|
350 | unnecessary protocol components. It SHOULD NOT be used by clients, |
---|
351 | but MAY be supported by servers for backward compatibility. It is |
---|
352 | recognized by the server and client by the lack of TOKEN_PROTOCOL in |
---|
353 | the flags of the initial security context negotiation.</t> |
---|
354 | |
---|
355 | <t>The old protocol always uses the following steps: |
---|
356 | <list style='numbers'> |
---|
357 | <t>Client opens TCP connection to server.</t> |
---|
358 | |
---|
359 | <t>Client sends message with flags TOKEN_NOOP and |
---|
360 | TOKEN_CONTEXT_NEXT and an empty payload.</t> |
---|
361 | |
---|
362 | <t>Client calls gss_init_sec_context and sends message with the |
---|
363 | results and flags TOKEN_CONTEXT. The client MUST pass |
---|
364 | GSS_C_MUTUAL_FLAG, GSS_C_CONF_FLAG, and GSS_C_INTEG_FLAG as |
---|
365 | requested flags and SHOULD pass GSS_C_REPLAY_FLAG and |
---|
366 | GSS_C_SEQUENCE_FLAG, although the version one protocol does not |
---|
367 | check the results of this negotiation.</t> |
---|
368 | |
---|
369 | <t>Server replies with the results of gss_accept_sec_context and |
---|
370 | flags TOKEN_CONTEXT.</t> |
---|
371 | |
---|
372 | <t>Client calls gss_init_sec_context again with the data from |
---|
373 | the server and replies with the results and flags TOKEN_CONTEXT, |
---|
374 | using the same requested flags as described above.</t> |
---|
375 | |
---|
376 | <t>Server and client repeat, passing in the payload from the |
---|
377 | last packet from the other side, for as long as GSS-API |
---|
378 | indicates that continuation is required. Each of these packets |
---|
379 | have only TOKEN_CONTEXT set in the flags.</t> |
---|
380 | |
---|
381 | <t>Client sends command with flags TOKEN_DATA and TOKEN_SEND_MIC |
---|
382 | and the following payload format: four-octet number of |
---|
383 | arguments, and then for each argument, a four-octet length and |
---|
384 | then the argument value. All numbers are in network type order. |
---|
385 | The payload MUST be protected with gss_wrap and the |
---|
386 | conf_req_flag parameter of gss_wrap MUST be set to non-zero, |
---|
387 | requesting both confidentiality and integrity services.</t> |
---|
388 | |
---|
389 | <t>Server accepts and decrypts data, generates a MIC with |
---|
390 | gss_get_mic, and sends the MIC back to the client with flags |
---|
391 | TOKEN_MIC. This is the only packet that isn't encrypted with |
---|
392 | gss_wrap. Client receives and then SHOULD verify this MIC.</t> |
---|
393 | |
---|
394 | <t>Server runs the command, collects the output, and sends the |
---|
395 | output back with flags TOKEN_DATA and the following payload |
---|
396 | format: four-octet exit status, four-octet data length, data. |
---|
397 | All numbers are in network byte order. The exit status is 0 if |
---|
398 | there were no errors and non-zero otherwise, where the meaning |
---|
399 | of non-zero values are defined by the application. The payload |
---|
400 | MUST be protected with gss_wrap with a conf_req_flag set to |
---|
401 | non-zero.</t> |
---|
402 | |
---|
403 | <t>Server and client close connection.</t> |
---|
404 | </list> |
---|
405 | </t> |
---|
406 | </section> |
---|
407 | |
---|
408 | <section anchor='security' title='Security Considerations'> |
---|
409 | <t>It would be preferrable to insist on replay and sequence |
---|
410 | protection (GSS_C_REPLAY_FLAG and GSS_C_SEQUENCE_FLAG) for all |
---|
411 | contexts, but some older Kerberos GSS-API implementations don't |
---|
412 | support this and hence it is not mandatory in the protocol. Clients |
---|
413 | SHOULD always request replay and sequence protection, however, and |
---|
414 | servers MAY require such protection be negotiated.</t> |
---|
415 | |
---|
416 | <t>The old protocol doesn't provide integrity protection for the |
---|
417 | flags, but since it always follows the same fixed sequence of |
---|
418 | operations, this should pose no security concerns in practice. The |
---|
419 | new protocol only uses the flag field outside of the encrypted |
---|
420 | section of the packet for initial negotiation and closes the |
---|
421 | connection if the flags aren't what was expected (avoiding a |
---|
422 | down-negotiation attack).</t> |
---|
423 | |
---|
424 | <t>In the old protocol, the server calculated and sent a MIC back to |
---|
425 | the client, which then verified that the command as received by the |
---|
426 | server was correct. Not only does GSS-API already provide integrity |
---|
427 | protection, but this verification also happens after the server has |
---|
428 | already started running the command. It has been dropped in the new |
---|
429 | protocol.</t> |
---|
430 | |
---|
431 | <t>The old protocol doesn't require the client and server check the |
---|
432 | results of the GSS-API flag negotiation, although all old protocol |
---|
433 | clients passed GSS_C_MUTUAL_FLAG. However, the old protocol |
---|
434 | requires gss_wrap be used for all payload with conf_req_flag set to |
---|
435 | non-zero, so any context that didn't negotiate confidentiality and |
---|
436 | integrity services would fail later.</t> |
---|
437 | </section> |
---|
438 | </middle> |
---|
439 | <back> |
---|
440 | <section anchor='credits' title='Acknowledgements'> |
---|
441 | <t>The original remctl protocol design was done by Anton Ushakov, |
---|
442 | with input from Russ Allbery and Roland Schemers. Thank you to |
---|
443 | David Hoffman and Mike Newton for their review of the version 2 |
---|
444 | remctl protocol.</t> |
---|
445 | </section> |
---|
446 | </back> |
---|
447 | </rfc> |
---|