blob: 69a35ec6cf6a093f6ce2c206c1b231551212624d [file] [log] [blame]
Sean Middleditchb9e48642009-03-12 23:33:27 -04001=====================================================================
2 libtelnet - TELNET protocol handling library
3=====================================================================
4
Sean Middleditch892c5f12009-03-14 13:39:07 -04005 http://github.com/elanthis/libtelnet
6
7 Sean Middleditch
8 sean@sourcemud.org
Sean Middleditchb9e48642009-03-12 23:33:27 -04009
10---------------------------------------------------------------------
11The author or authors of this code dedicate any and all copyright
12interest in this code to the public domain. We make this dedication
13for the benefit of the public at large and to the detriment of our
14heirs and successors. We intend this dedication to be an overt act of
15relinquishment in perpetuity of all present and future rights to this
16code under copyright law.
17---------------------------------------------------------------------
18
Sean Middleditch9d2f98a2009-03-14 05:24:56 -040019*** TODO ***
20
21 - RFC 1143 option negotiation algorithm
22 - automatic MCCP2 handling (controllable by host app)
Sean Middleditch9d2f98a2009-03-14 05:24:56 -040023 ? ZMP parsing
24 ? MSSP parsing
25 ? ENVIRON/NEW-ENVIRON parsing
26 ? telnet-status testing tool
Sean Middleditch9d2f98a2009-03-14 05:24:56 -040027
Sean Middleditchb9e48642009-03-12 23:33:27 -040028I. INTRODUCTION
29=====================================================================
30
31libtelnet provides safe and correct handling of the core TELNET
32protocol. It does not include any "smarts," and all use of the
33protocol (such as deciding which options to support, enabling
34and disabling options, or processing subrequests) must be implemented
35by the application author.
36
Sean Middleditch892c5f12009-03-14 13:39:07 -040037For more information on the TELNET protocol, see:
38
39 http://www.faqs.org/rfcs/rfc854.html
40
Sean Middleditchb9e48642009-03-12 23:33:27 -040041II. LIBTELNET API
42=====================================================================
43
Sean Middleditch892c5f12009-03-14 13:39:07 -040044The libtelnet API contains several distinct parts. The first part is
45the basic initialization and deinitialization routines. The second
46part is a single function for pushing received data into the
47libtelnet processor. The third part is the libtelnet_send_*()
48functions, which generate TELNET commands and ensure data is properly
Sean Middleditch637df7f2009-03-15 12:57:32 -040049formatted before sending over the wire. The final part is the event
50handler interface.
Sean Middleditch892c5f12009-03-14 13:39:07 -040051
52IIa. Initialization
53
54 struct libtelnet_t;
55 This structure represents the state of the TELNET protocol for a
56 single connection. Each connection utilizing TELNET must have
57 its own libtelnet_t structure, which is passed to all libtelnet
58 API calls.
59
Sean Middleditch812358d2009-03-15 23:24:03 -040060 void libtelnet_init(libtelnet_t *telnet, libtelnet_event_handler_t handler,
61 libtelnet_mode_t mode, void *user_data);
Sean Middleditch892c5f12009-03-14 13:39:07 -040062 The libtelnet_init() function is responsible for initializing
63 the data in a libtelnet_t structure. It must be called
64 immediately after establishing a connection and before any other
65 libtelnet API calls are made.
66
Sean Middleditch637df7f2009-03-15 12:57:32 -040067 The handler parameter must be a function matching the
68 libtelnet_event_handler_t definition. More information about
69 events can be found in section IId.
Sean Middleditch30323022009-03-14 21:45:28 -040070
Sean Middleditch9f79cc52009-03-15 13:39:24 -040071 The user_data parameter is passed to the event handler whenver it
72 is invoked. This will usually be a structure container
73 information about the connection, including a socket descriptor
74 for implementing LIBTELNET_EV_SEND event handling.
75
Sean Middleditchf66a7ee2009-03-15 11:54:07 -040076 The mode parameter must be one of LIBTELNET_MODE_SERVER,
77 LIBTELNET_MODE_CLIENT, or LIBTELNET_MODE_PROXY. These slightly
78 alter the behavior of libtelnet in certain instances. If you are
79 implementing a TELNET server, use the SERVER mode. If you are
80 implementing a client, use the CLIENT mode. The PROXY mode
81 enables special behavior for telnet-proxy (or similar
82 applications).
Sean Middleditch892c5f12009-03-14 13:39:07 -040083
Sean Middleditch812358d2009-03-15 23:24:03 -040084 boid libtelnet_free(libtelnet_t *telnet);
Sean Middleditch892c5f12009-03-14 13:39:07 -040085 Releases any internal memory allocated by libtelnet. This must
86 be called whenever a connection is closed, or you will incur
87 memory leaks.
88
89IIb. Receiving Data
90
Sean Middleditch812358d2009-03-15 23:24:03 -040091 void libtelnet_push(libtelnet_t *telnet,
Sean Middleditch892c5f12009-03-14 13:39:07 -040092 unsigned char *buffer, unsigned int size, void *user_data);
93 When your application receives data over the socket from the
94 remote end, it must pass the received bytes into this function.
Sean Middleditch637df7f2009-03-15 12:57:32 -040095
96 As the TELNET stream is parsed, events will be generated and
97 passed to the event handler given to libtelnet_init(). Of
98 particular interest for data receiving is the LIBTELNET_EV_DATA
99 event, which is triggered for any regular data such as user
100 input or server process output.
Sean Middleditch892c5f12009-03-14 13:39:07 -0400101
102IIc. Sending Data
103
Sean Middleditch637df7f2009-03-15 12:57:32 -0400104 All of the libtelnet_send_*() functions will invoke the
Sean Middleditch9f79cc52009-03-15 13:39:24 -0400105 LIBTELNET_EV_SEND event.
Sean Middleditch637df7f2009-03-15 12:57:32 -0400106
107 Note: it is very important that ALL data sent to the remote end of
108 the connection be passed through libtelnet. All user input or
109 process output that you wish to send over the wire should be given
110 to libtelnet_send_data(). Do NOT send or buffer unprocessed output
111 data directly!
Sean Middleditch892c5f12009-03-14 13:39:07 -0400112
Sean Middleditch812358d2009-03-15 23:24:03 -0400113 void libtelnet_send_command(libtelnet_t *telnet, unsigned char cmd);
Sean Middleditch892c5f12009-03-14 13:39:07 -0400114 Sends a single "simple" TELNET command, such as the GO-AHEAD
115 commands (255 249).
116
Sean Middleditch812358d2009-03-15 23:24:03 -0400117 void libtelnet_send_negotiate(libtelnet_t *telnet,
Sean Middleditch9f79cc52009-03-15 13:39:24 -0400118 unsigned char cmd, unsigned char opt);
Sean Middleditch892c5f12009-03-14 13:39:07 -0400119 Sends a TELNET negotiation command. The cmd parameter must be
120 one of LIBTELNET_WILL, LIBTELNET_DONT, LIBTELNET_DO, or
121 LIBTELNET_DONT. The opt parameter is the option to
122 negotiate.
123
Sean Middleditch812358d2009-03-15 23:24:03 -0400124 void libtelnet_send_data(libtelnet_t *telnet, unsigned char *buffer,
125 unsigned int size);
Sean Middleditch892c5f12009-03-14 13:39:07 -0400126 Sends raw data, which would be either the process output from
127 a server or the user input from a client.
128
Sean Middleditch812358d2009-03-15 23:24:03 -0400129 void libtelnet_send_subnegotiation(libtelnet_t *telnet,
Sean Middleditch9f79cc52009-03-15 13:39:24 -0400130 unsigned char opt, unsigned char *buffer, unsigned int size);
Sean Middleditch892c5f12009-03-14 13:39:07 -0400131 Sends a TELNET sub-negotiation command. The opt parameter
132 is the sub-negotiation option.
133
Sean Middleditch637df7f2009-03-15 12:57:32 -0400134IId. Event Handling
Sean Middleditch892c5f12009-03-14 13:39:07 -0400135
Sean Middleditch637df7f2009-03-15 12:57:32 -0400136 libtelnet relies on an event-handling mechanism for processing
137 the parsed TELNET protocol stream as well as for buffering and
138 sending output data.
Sean Middleditch892c5f12009-03-14 13:39:07 -0400139
Sean Middleditch637df7f2009-03-15 12:57:32 -0400140 When you initialize a libtelnet_t structure with libtelnet_init()
141 you had to pass in an event handler function. This function must
142 meet the following prototype:
Sean Middleditch30323022009-03-14 21:45:28 -0400143
Sean Middleditch637df7f2009-03-15 12:57:32 -0400144 void (libtelnet_t *telnet, libtelnet_event_t *event,
Sean Middleditch9f79cc52009-03-15 13:39:24 -0400145 void *user_data);
146
147 The event structure is detailed below. The user_data value is the
148 pointer passed to libtelnet_init().
Sean Middleditch637df7f2009-03-15 12:57:32 -0400149
150 struct libtelnet_event_t {
Sean Middleditch637df7f2009-03-15 12:57:32 -0400151 unsigned char *buffer;
152 unsigned int size;
Sean Middleditch812358d2009-03-15 23:24:03 -0400153 libtelnet_event_type_t type;
154 unsigned char command;
155 unsigned char telopt;
156 unsigned char accept;
Sean Middleditch637df7f2009-03-15 12:57:32 -0400157 };
158
159 The enumeration values of libtelnet_event_type_t are described in
160 detail below. Whenever the the event handler is invoked, the
161 application must look at the event->type value and do any
162 necessary processing.
163
164 The only event that MUST be implemented is LIBTELNET_EV_SEND.
165 Most applications will also always want to implement the event
166 LIBTELNET_EV_DATA.
167
168 Here is an example event handler implementation which includes
169 handlers for several important events.
170
Sean Middleditch812358d2009-03-15 23:24:03 -0400171 void my_event_handler(libtelnet_t *telnet, libtelnet_event_t *ev,
172 void *user_data) {
Sean Middleditch637df7f2009-03-15 12:57:32 -0400173 struct user_info *user = (struct user_info *)user_data;
174
175 switch (ev->type) {
176 case LIBTELNET_EV_DATA:
177 process_user_input(user, event->buffer, event->size);
178 break;
179 case LIBTELNET_EV_SEND:
180 write_to_descriptor(user, event->buffer, event->size);
181 break;
182 case LIBTELNET_EV_ERROR:
183 fatal_error("TELNET error: %s", event->buffer);
184 break;
185 }
Sean Middleditch30323022009-03-14 21:45:28 -0400186 }
187
Sean Middleditch637df7f2009-03-15 12:57:32 -0400188 LIBTELNET_EV_DATA:
189 The DATA event is triggered whenever regular data (not part of
190 any special TELNET command) is received. For a client, this
191 will be process output from the server. For a server, this will
192 be input typed by the user.
Sean Middleditch30323022009-03-14 21:45:28 -0400193
Sean Middleditch637df7f2009-03-15 12:57:32 -0400194 The event->buffer value will contain the bytes received and the
195 event->size value will contain the number of bytes received.
196 Note that event->buffer is not NUL terminated!
Sean Middleditch30323022009-03-14 21:45:28 -0400197
Sean Middleditch637df7f2009-03-15 12:57:32 -0400198 NOTE: there is no guarantee that user input or server output
199 will be received in whole lines. If you wish to process data
200 a line at a time, you are responsible for buffering the data and
201 checking for line terminators yourself!
202
203 LIBTELNET_EV_SEND:
204 This event is sent whenever libtelnet has generated data that
205 must be sent over the wire to the remove end. Generally that
206 means calling send() or adding the data to your application's
207 output buffer.
Sean Middleditch30323022009-03-14 21:45:28 -0400208
Sean Middleditch637df7f2009-03-15 12:57:32 -0400209 The event->buffer value will contain the bytes to send and the
210 event->size value will contain the number of bytes to send.
211 Note that event->buffer is not NUL terminated, and may include
212 NUL characters in its data, so always use event->size!
Sean Middleditch30323022009-03-14 21:45:28 -0400213
Sean Middleditch637df7f2009-03-15 12:57:32 -0400214 NOTE: Your SEND event handler must send or buffer the data in
215 its raw form as provided by libtelnet. If you wish to perform
216 any kind of preprocessing on data you want to send to the other
217
218 LIBTELNET_EV_IAC:
219 The IAC event is triggered whenever a simple IAC command is
220 received, such as the IAC EOR (end of record, also called
221 go ahead or GA) command.
Sean Middleditch892c5f12009-03-14 13:39:07 -0400222
Sean Middleditch637df7f2009-03-15 12:57:32 -0400223 The command received is in the event->command value.
Sean Middleditch892c5f12009-03-14 13:39:07 -0400224
Sean Middleditch637df7f2009-03-15 12:57:32 -0400225 The necessary processing depends on the specific commands; see
226 the TELNET RFC for more information.
227
228 LIBTELNET_EV_NEGOTIATE:
229 The NEGOTIATE event is sent when a TELNET neogitiation command
230 is received.
Sean Middleditch892c5f12009-03-14 13:39:07 -0400231
Sean Middleditch637df7f2009-03-15 12:57:32 -0400232 The event->command value will be one of LIBTELNET_WILL,
233 LIBTELNET_WONT, LIBTELNET_DO, or LIBTELNET_DONT. The
234 event->telopt value will contain the option value being
235 negotiated.
Sean Middleditch892c5f12009-03-14 13:39:07 -0400236
237 libtelnet does not currently manage negotiation for you. For
238 best practice in implementing TELNET negotiation, see:
239
240 http://www.faqs.org/rfcs/rfc1143.html
241
Sean Middleditch637df7f2009-03-15 12:57:32 -0400242 LIBTELNET_EV_SUBNEGOTIATION:
243 Triggered whenever a TELNET sub-negotiation has been received.
Sean Middleditch892c5f12009-03-14 13:39:07 -0400244 Sub-negotiations include the NAWS option for communicating
245 terminal size to a server, the NEW-ENVIRON and TTYPE options
246 for negotiating terminal features, and MUD-centric protocols
247 such as ZMP, MSSP, and MCCP2.
248
Sean Middleditch637df7f2009-03-15 12:57:32 -0400249 The event->telopt value is the option under sub-negotiation.
250 The remaining data (if any) is passed in event->buffer and
251 event->size. Note that most subnegotiation commands can
252 include embedded NUL bytes in the subnegotiation data, and
253 the data event->buffer is not NUL terminated, so always use
254 the event->size value!
Sean Middleditch892c5f12009-03-14 13:39:07 -0400255
Sean Middleditch637df7f2009-03-15 12:57:32 -0400256 The meaning and necessary processing for subnegotiations are
257 defined in various TELNET RFCs and other informal
258 specifications. A subnegotiation should never be sent unless
259 the specific option has been enabled through the use of the
260 telnet negotiation feature.
Sean Middleditch892c5f12009-03-14 13:39:07 -0400261
Sean Middleditch637df7f2009-03-15 12:57:32 -0400262 LIBTELNET_EV_COMPRESS
263 The COMPRESS event notifies the app that COMPRESS2/MCCP2
264 compression has begun or ended. Only servers can send compressed
265 data, and hence only clients will receive compressed data.
Sean Middleditchb9e48642009-03-12 23:33:27 -0400266
Sean Middleditch637df7f2009-03-15 12:57:32 -0400267 The event->command value will be 1 if compression has started and
268 will be 0 if compression has ended.
Sean Middleditch16992272009-03-15 19:42:03 -0400269
270 LIBTELNET_EV_WARNING
271 The WARNING event is sent whenever something has gone wrong
272 inside of libtelnet (possibly due to malformed data sent by the
273 other end) but which recovery is (likely) possible. It may be
274 safe to continue using the connection, but some data may have
275 been lost or incorrectly interpreted.
Sean Middleditch637df7f2009-03-15 12:57:32 -0400276
277 The event->buffer value will contain a NUL terminated string
278 explaining the error, and the event->size value containers the
279 length of the string.
280
Sean Middleditch16992272009-03-15 19:42:03 -0400281 LIBTELNET_EV_ERROR
282 Similar to the WARNING event, the ERROR event is sent whenever
283 something has gone wrong. ERROR events are non-recoverable,
284 however, and the application should immediately close the
285 connection. Whatever has happened is likely going only to
286 result in garbage from libtelnet. This is most likely to
287 happen when a COMPRESS2 stream fails, but other problems can
288 occur.
289
290 The event->buffer value will contain a NUL terminated string
291 explaining the error, and the event->size value containers the
292 length of the string.
Sean Middleditch637df7f2009-03-15 12:57:32 -0400293
294III. INTEGRATING LIBTELNET WITH COMMON MUDS
Sean Middleditchb9e48642009-03-12 23:33:27 -0400295=====================================================================
296
Sean Middleditch637df7f2009-03-15 12:57:32 -0400297FIXME: fill in some notes about how to splice in libtelnet with
298common Diku/Merc/Circle/etc. MUD codebases.
Sean Middleditchb9e48642009-03-12 23:33:27 -0400299
Sean Middleditch892c5f12009-03-14 13:39:07 -0400300IV. SAFETY AND CORRECTNESS CONSIDERATIONS
Sean Middleditchb9e48642009-03-12 23:33:27 -0400301=====================================================================
302
Sean Middleditch892c5f12009-03-14 13:39:07 -0400303Your existing application may make heavy use of its own output
304buffering and transmission commands, including hand-made routines
305for sending TELNET commands and sub-negotiation requests. There are
306at times subtle issues that need to be handled when communication
307over the TELNET protocol, not least of which is the need to escape
308any byte value 0xFF with a special TELNET command.
Sean Middleditchb9e48642009-03-12 23:33:27 -0400309
Sean Middleditch892c5f12009-03-14 13:39:07 -0400310For these reasons, it is very important that applications making use
311of libtelnet always make use of the libtelnet_send_*() family of
312functions for all data being sent over the TELNET connection.
313
Sean Middleditch637df7f2009-03-15 12:57:32 -0400314In particular, if you are writing a client, all user input must be
315passed through to libtelnet_send_data(). This also includes any
316input generated automatically by scripts, triggers, or macros.
317
318For a server, any and all output -- including ANSI/VT100 escape
319codes, regular text, newlines, and so on -- must be passed through
320to libtelnet_send_data().
321
322Any TELNET commands that are to be sent must be given to one of the
323following: libtelnet_send_command, libtelnet_send_negotiate, or
324libtelnet_send_subnegotiation().
325
326If you are attempting to enable COMPRESS2/MCCP2, you must use the
327libtelnet_begin_compress2() function.
328
Sean Middleditch892c5f12009-03-14 13:39:07 -0400329V. MCCP2 COMPRESSION
Sean Middleditchb9e48642009-03-12 23:33:27 -0400330=====================================================================
331
Sean Middleditch892c5f12009-03-14 13:39:07 -0400332The MCCP2 (COMPRESS2) TELNET extension allows for the compression of
333all traffic sent from server to client. For more information:
334
335 http://www.mudbytes.net/index.php?a=articles&s=mccp
336
Sean Middleditch637df7f2009-03-15 12:57:32 -0400337In order for libtelnet to support MCCP2, zlib must be installed and
338enabled when compiling libtelnet. Use -DHAVE_ZLIB to enable zlib
339when compiling libtelnet.c and pass -lz to the linker to link in the
340zlib shared library.
341
Sean Middleditch892c5f12009-03-14 13:39:07 -0400342libtelnet transparently supports MCCP2. For a server to support
343MCCP2, the application must begin negotiation of the COMPRESS2
344option using libtelnet_send_negotiate(), for example:
345
346 libtelnet_send_negotiate(&telnet, LIBTELNET_WILL,
347 LIBTELNET_OPTION_COMPRESS2, user_data);
348
Sean Middleditch637df7f2009-03-15 12:57:32 -0400349If a favorable DO COMPRESS2 is sent back from the client (processed
350in a LIBTELNET_EV_NEGOTIATE event, with event->command equal to
351LIBTELNET_DO and event->telopt equal to LIBTELNET_TELOPT_COMPRESS2),
352then the server application can begin compression at any time by
353calling libtelnet_begin_compress2().
Sean Middleditch892c5f12009-03-14 13:39:07 -0400354
Sean Middleditch637df7f2009-03-15 12:57:32 -0400355If a connection is in PROXY mode and COMPRESS2 support is enabled
356then libtelnet will automatically detect the start of a COMPRESS2
357stream, in either the sending or receiving direction.
Sean Middleditch892c5f12009-03-14 13:39:07 -0400358
359VI. TELNET PROXY UTILITY
360=====================================================================
361
362The telnet-proxy utility is a small application that serves both as
363a testbed for libtelnet and as a powerful debugging tool for TELNET
364servers and clients.
365
366To use telnet-proxy, you must first compile it using:
367
368 $ make
369
370If you do not have zlib installed and wish to disable MCCP2 support
371then you must first edit the Makefile and remove the -DHAVE_ZLIB and
372the -lz from the compile flags.
373
Sean Middleditchd88f1832009-03-15 01:06:17 -0400374To run telnet-proxy, you simply give it the server's host name or
375IP address, the server's port number, and the port number that
376telnet-proxy should listen on. For example, to connect to the server
377on mud.example.com port 7800 and to listen on port 5000, run:
Sean Middleditch892c5f12009-03-14 13:39:07 -0400378
Sean Middleditchd88f1832009-03-15 01:06:17 -0400379 $ ./telnet-proxy mud.example.com 7800 5000
Sean Middleditch892c5f12009-03-14 13:39:07 -0400380
381You can then connect to the host telnet-proxy is running on (e.g.
Sean Middleditchd88f1832009-03-15 01:06:17 -0400382127.0.0.1) on port 500 and you will automatically be proxied into
383mud.example.com.
Sean Middleditch892c5f12009-03-14 13:39:07 -0400384
385telnet-proxy will display status information about the data
Sean Middleditchaefcd0c2009-03-15 13:16:44 -0400386passing through both ends of the tunnel. telnet-proxy can only
387support a single tunnel at a time. It will continue running until
388an error occurs or a terminating signal is sent to the proxy
389process.