blob: ce695bd5671478b0fa7fccc69e3782aaaba132af [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)
23 - efficient one-byte sub-requests
24 ? MCCP1
25 ? ZMP parsing
26 ? MSSP parsing
27 ? ENVIRON/NEW-ENVIRON parsing
28 ? telnet-status testing tool
29 ? few options to make telnet-proxy even more useful
30
Sean Middleditchb9e48642009-03-12 23:33:27 -040031I. INTRODUCTION
32=====================================================================
33
34libtelnet provides safe and correct handling of the core TELNET
35protocol. It does not include any "smarts," and all use of the
36protocol (such as deciding which options to support, enabling
37and disabling options, or processing subrequests) must be implemented
38by the application author.
39
Sean Middleditch892c5f12009-03-14 13:39:07 -040040For more information on the TELNET protocol, see:
41
42 http://www.faqs.org/rfcs/rfc854.html
43
Sean Middleditchb9e48642009-03-12 23:33:27 -040044II. LIBTELNET API
45=====================================================================
46
Sean Middleditch892c5f12009-03-14 13:39:07 -040047The libtelnet API contains several distinct parts. The first part is
48the basic initialization and deinitialization routines. The second
49part is a single function for pushing received data into the
50libtelnet processor. The third part is the libtelnet_send_*()
51functions, which generate TELNET commands and ensure data is properly
Sean Middleditch637df7f2009-03-15 12:57:32 -040052formatted before sending over the wire. The final part is the event
53handler interface.
Sean Middleditch892c5f12009-03-14 13:39:07 -040054
55IIa. Initialization
56
57 struct libtelnet_t;
58 This structure represents the state of the TELNET protocol for a
59 single connection. Each connection utilizing TELNET must have
60 its own libtelnet_t structure, which is passed to all libtelnet
61 API calls.
62
63 void libtelnet_init(struct libtelnet_t *telnet,
Sean Middleditch637df7f2009-03-15 12:57:32 -040064 libtelnet_event_handler_t handler, enum libtelnet_mode_t mode);
Sean Middleditch892c5f12009-03-14 13:39:07 -040065 The libtelnet_init() function is responsible for initializing
66 the data in a libtelnet_t structure. It must be called
67 immediately after establishing a connection and before any other
68 libtelnet API calls are made.
69
Sean Middleditch637df7f2009-03-15 12:57:32 -040070 The handler parameter must be a function matching the
71 libtelnet_event_handler_t definition. More information about
72 events can be found in section IId.
Sean Middleditch30323022009-03-14 21:45:28 -040073
Sean Middleditchf66a7ee2009-03-15 11:54:07 -040074 The mode parameter must be one of LIBTELNET_MODE_SERVER,
75 LIBTELNET_MODE_CLIENT, or LIBTELNET_MODE_PROXY. These slightly
76 alter the behavior of libtelnet in certain instances. If you are
77 implementing a TELNET server, use the SERVER mode. If you are
78 implementing a client, use the CLIENT mode. The PROXY mode
79 enables special behavior for telnet-proxy (or similar
80 applications).
Sean Middleditch892c5f12009-03-14 13:39:07 -040081
82 boid libtelnet_free(struct libtelnet_t *telnet);
83 Releases any internal memory allocated by libtelnet. This must
84 be called whenever a connection is closed, or you will incur
85 memory leaks.
86
87IIb. Receiving Data
88
89 void libtelnet_push(struct libtelnet_t *telnet,
90 unsigned char *buffer, unsigned int size, void *user_data);
91 When your application receives data over the socket from the
92 remote end, it must pass the received bytes into this function.
Sean Middleditch637df7f2009-03-15 12:57:32 -040093
94 As the TELNET stream is parsed, events will be generated and
95 passed to the event handler given to libtelnet_init(). Of
96 particular interest for data receiving is the LIBTELNET_EV_DATA
97 event, which is triggered for any regular data such as user
98 input or server process output.
Sean Middleditch892c5f12009-03-14 13:39:07 -040099
100IIc. Sending Data
101
Sean Middleditch637df7f2009-03-15 12:57:32 -0400102 All of the libtelnet_send_*() functions will invoke the
103 LIBTELNET_EV_SEND event. The user_data parameter to each of these
104 functions is passed through to the callback.
105
106 Note: it is very important that ALL data sent to the remote end of
107 the connection be passed through libtelnet. All user input or
108 process output that you wish to send over the wire should be given
109 to libtelnet_send_data(). Do NOT send or buffer unprocessed output
110 data directly!
Sean Middleditch892c5f12009-03-14 13:39:07 -0400111
112 void libtelnet_send_command(struct libtelnet_t *telnet,
113 unsigned char cmd, void *user_data);
114 Sends a single "simple" TELNET command, such as the GO-AHEAD
115 commands (255 249).
116
117 void libtelnet_send_negotiate(struct libtelnet_t *telnet,
118 unsigned char cmd, unsigned char opt, void *user_data);
119 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
124 void libtelnet_send_data(struct libtelnet_t *telnet,
125 unsigned char *buffer, unsigned int size, void *user_data);
126 Sends raw data, which would be either the process output from
127 a server or the user input from a client.
128
129 void libtelnet_send_subnegotiation(struct libtelnet_t *telnet,
130 unsigned char opt, unsigned char *buffer, unsigned int size,
131 void *user_data);
132 Sends a TELNET sub-negotiation command. The opt parameter
133 is the sub-negotiation option.
134
Sean Middleditch637df7f2009-03-15 12:57:32 -0400135IId. Event Handling
Sean Middleditch892c5f12009-03-14 13:39:07 -0400136
Sean Middleditch637df7f2009-03-15 12:57:32 -0400137 libtelnet relies on an event-handling mechanism for processing
138 the parsed TELNET protocol stream as well as for buffering and
139 sending output data.
Sean Middleditch892c5f12009-03-14 13:39:07 -0400140
Sean Middleditch637df7f2009-03-15 12:57:32 -0400141 When you initialize a libtelnet_t structure with libtelnet_init()
142 you had to pass in an event handler function. This function must
143 meet the following prototype:
Sean Middleditch30323022009-03-14 21:45:28 -0400144
Sean Middleditch637df7f2009-03-15 12:57:32 -0400145 void (libtelnet_t *telnet, libtelnet_event_t *event,
146 void *user_data);
147
148 The libtelnet_event_t structure has the following definition:
149
150 struct libtelnet_event_t {
151 enum libtelnet_event_type_t type;
152 unsigned char command;
153 unsigned char telopt;
154 unsigned char *buffer;
155 unsigned int size;
156 };
157
158 The enumeration values of libtelnet_event_type_t are described in
159 detail below. Whenever the the event handler is invoked, the
160 application must look at the event->type value and do any
161 necessary processing.
162
163 The only event that MUST be implemented is LIBTELNET_EV_SEND.
164 Most applications will also always want to implement the event
165 LIBTELNET_EV_DATA.
166
167 Here is an example event handler implementation which includes
168 handlers for several important events.
169
170 void my_event_handler(struct libtelnet_t *telnet,
171 libtelnet_event_t *ev, void *user_data) {
172 struct user_info *user = (struct user_info *)user_data;
173
174 switch (ev->type) {
175 case LIBTELNET_EV_DATA:
176 process_user_input(user, event->buffer, event->size);
177 break;
178 case LIBTELNET_EV_SEND:
179 write_to_descriptor(user, event->buffer, event->size);
180 break;
181 case LIBTELNET_EV_ERROR:
182 fatal_error("TELNET error: %s", event->buffer);
183 break;
184 }
Sean Middleditch30323022009-03-14 21:45:28 -0400185 }
186
Sean Middleditch637df7f2009-03-15 12:57:32 -0400187 LIBTELNET_EV_DATA:
188 The DATA event is triggered whenever regular data (not part of
189 any special TELNET command) is received. For a client, this
190 will be process output from the server. For a server, this will
191 be input typed by the user.
Sean Middleditch30323022009-03-14 21:45:28 -0400192
Sean Middleditch637df7f2009-03-15 12:57:32 -0400193 The event->buffer value will contain the bytes received and the
194 event->size value will contain the number of bytes received.
195 Note that event->buffer is not NUL terminated!
Sean Middleditch30323022009-03-14 21:45:28 -0400196
Sean Middleditch637df7f2009-03-15 12:57:32 -0400197 NOTE: there is no guarantee that user input or server output
198 will be received in whole lines. If you wish to process data
199 a line at a time, you are responsible for buffering the data and
200 checking for line terminators yourself!
201
202 LIBTELNET_EV_SEND:
203 This event is sent whenever libtelnet has generated data that
204 must be sent over the wire to the remove end. Generally that
205 means calling send() or adding the data to your application's
206 output buffer.
Sean Middleditch30323022009-03-14 21:45:28 -0400207
Sean Middleditch637df7f2009-03-15 12:57:32 -0400208 The event->buffer value will contain the bytes to send and the
209 event->size value will contain the number of bytes to send.
210 Note that event->buffer is not NUL terminated, and may include
211 NUL characters in its data, so always use event->size!
Sean Middleditch30323022009-03-14 21:45:28 -0400212
Sean Middleditch637df7f2009-03-15 12:57:32 -0400213 NOTE: Your SEND event handler must send or buffer the data in
214 its raw form as provided by libtelnet. If you wish to perform
215 any kind of preprocessing on data you want to send to the other
216
217 LIBTELNET_EV_IAC:
218 The IAC event is triggered whenever a simple IAC command is
219 received, such as the IAC EOR (end of record, also called
220 go ahead or GA) command.
Sean Middleditch892c5f12009-03-14 13:39:07 -0400221
Sean Middleditch637df7f2009-03-15 12:57:32 -0400222 The command received is in the event->command value.
Sean Middleditch892c5f12009-03-14 13:39:07 -0400223
Sean Middleditch637df7f2009-03-15 12:57:32 -0400224 The necessary processing depends on the specific commands; see
225 the TELNET RFC for more information.
226
227 LIBTELNET_EV_NEGOTIATE:
228 The NEGOTIATE event is sent when a TELNET neogitiation command
229 is received.
Sean Middleditch892c5f12009-03-14 13:39:07 -0400230
Sean Middleditch637df7f2009-03-15 12:57:32 -0400231 The event->command value will be one of LIBTELNET_WILL,
232 LIBTELNET_WONT, LIBTELNET_DO, or LIBTELNET_DONT. The
233 event->telopt value will contain the option value being
234 negotiated.
Sean Middleditch892c5f12009-03-14 13:39:07 -0400235
236 libtelnet does not currently manage negotiation for you. For
237 best practice in implementing TELNET negotiation, see:
238
239 http://www.faqs.org/rfcs/rfc1143.html
240
Sean Middleditch637df7f2009-03-15 12:57:32 -0400241 LIBTELNET_EV_SUBNEGOTIATION:
242 Triggered whenever a TELNET sub-negotiation has been received.
Sean Middleditch892c5f12009-03-14 13:39:07 -0400243 Sub-negotiations include the NAWS option for communicating
244 terminal size to a server, the NEW-ENVIRON and TTYPE options
245 for negotiating terminal features, and MUD-centric protocols
246 such as ZMP, MSSP, and MCCP2.
247
Sean Middleditch637df7f2009-03-15 12:57:32 -0400248 The event->telopt value is the option under sub-negotiation.
249 The remaining data (if any) is passed in event->buffer and
250 event->size. Note that most subnegotiation commands can
251 include embedded NUL bytes in the subnegotiation data, and
252 the data event->buffer is not NUL terminated, so always use
253 the event->size value!
Sean Middleditch892c5f12009-03-14 13:39:07 -0400254
Sean Middleditch637df7f2009-03-15 12:57:32 -0400255 The meaning and necessary processing for subnegotiations are
256 defined in various TELNET RFCs and other informal
257 specifications. A subnegotiation should never be sent unless
258 the specific option has been enabled through the use of the
259 telnet negotiation feature.
Sean Middleditch892c5f12009-03-14 13:39:07 -0400260
Sean Middleditch637df7f2009-03-15 12:57:32 -0400261 LIBTELNET_EV_COMPRESS
262 The COMPRESS event notifies the app that COMPRESS2/MCCP2
263 compression has begun or ended. Only servers can send compressed
264 data, and hence only clients will receive compressed data.
Sean Middleditchb9e48642009-03-12 23:33:27 -0400265
Sean Middleditch637df7f2009-03-15 12:57:32 -0400266 The event->command value will be 1 if compression has started and
267 will be 0 if compression has ended.
268
269 LIBTELNET_EV_ERROR
270 This event is called whenever an error occurs while trying to
271 process the TELNET protocol. This includes both invalid protocol
272 sequences (which are rare) and out of memory conditions.
273
274 With few exceptions, an error is non-recoverable, and the only
275 solid course of action is to close the connection. This is
276 especially true for any errors involving the COMPRESS2 option.
277
278 The event->buffer value will contain a NUL terminated string
279 explaining the error, and the event->size value containers the
280 length of the string.
281
282 FIXME: we should pass the error code in one of the fields, and
283 better document which errors are definitely non-recoverable and
284 which are maybe-recoverable (mostly those are just IAC-in-SB
285 errors... every other error is related to MCCP2 and usually
286 results in being unable to further read the stream).
287
288III. INTEGRATING LIBTELNET WITH COMMON MUDS
Sean Middleditchb9e48642009-03-12 23:33:27 -0400289=====================================================================
290
Sean Middleditch637df7f2009-03-15 12:57:32 -0400291FIXME: fill in some notes about how to splice in libtelnet with
292common Diku/Merc/Circle/etc. MUD codebases.
Sean Middleditchb9e48642009-03-12 23:33:27 -0400293
Sean Middleditch892c5f12009-03-14 13:39:07 -0400294IV. SAFETY AND CORRECTNESS CONSIDERATIONS
Sean Middleditchb9e48642009-03-12 23:33:27 -0400295=====================================================================
296
Sean Middleditch892c5f12009-03-14 13:39:07 -0400297Your existing application may make heavy use of its own output
298buffering and transmission commands, including hand-made routines
299for sending TELNET commands and sub-negotiation requests. There are
300at times subtle issues that need to be handled when communication
301over the TELNET protocol, not least of which is the need to escape
302any byte value 0xFF with a special TELNET command.
Sean Middleditchb9e48642009-03-12 23:33:27 -0400303
Sean Middleditch892c5f12009-03-14 13:39:07 -0400304For these reasons, it is very important that applications making use
305of libtelnet always make use of the libtelnet_send_*() family of
306functions for all data being sent over the TELNET connection.
307
Sean Middleditch637df7f2009-03-15 12:57:32 -0400308In particular, if you are writing a client, all user input must be
309passed through to libtelnet_send_data(). This also includes any
310input generated automatically by scripts, triggers, or macros.
311
312For a server, any and all output -- including ANSI/VT100 escape
313codes, regular text, newlines, and so on -- must be passed through
314to libtelnet_send_data().
315
316Any TELNET commands that are to be sent must be given to one of the
317following: libtelnet_send_command, libtelnet_send_negotiate, or
318libtelnet_send_subnegotiation().
319
320If you are attempting to enable COMPRESS2/MCCP2, you must use the
321libtelnet_begin_compress2() function.
322
Sean Middleditch892c5f12009-03-14 13:39:07 -0400323V. MCCP2 COMPRESSION
Sean Middleditchb9e48642009-03-12 23:33:27 -0400324=====================================================================
325
Sean Middleditch892c5f12009-03-14 13:39:07 -0400326The MCCP2 (COMPRESS2) TELNET extension allows for the compression of
327all traffic sent from server to client. For more information:
328
329 http://www.mudbytes.net/index.php?a=articles&s=mccp
330
Sean Middleditch637df7f2009-03-15 12:57:32 -0400331In order for libtelnet to support MCCP2, zlib must be installed and
332enabled when compiling libtelnet. Use -DHAVE_ZLIB to enable zlib
333when compiling libtelnet.c and pass -lz to the linker to link in the
334zlib shared library.
335
Sean Middleditch892c5f12009-03-14 13:39:07 -0400336libtelnet transparently supports MCCP2. For a server to support
337MCCP2, the application must begin negotiation of the COMPRESS2
338option using libtelnet_send_negotiate(), for example:
339
340 libtelnet_send_negotiate(&telnet, LIBTELNET_WILL,
341 LIBTELNET_OPTION_COMPRESS2, user_data);
342
Sean Middleditch637df7f2009-03-15 12:57:32 -0400343If a favorable DO COMPRESS2 is sent back from the client (processed
344in a LIBTELNET_EV_NEGOTIATE event, with event->command equal to
345LIBTELNET_DO and event->telopt equal to LIBTELNET_TELOPT_COMPRESS2),
346then the server application can begin compression at any time by
347calling libtelnet_begin_compress2().
Sean Middleditch892c5f12009-03-14 13:39:07 -0400348
Sean Middleditch637df7f2009-03-15 12:57:32 -0400349If a connection is in PROXY mode and COMPRESS2 support is enabled
350then libtelnet will automatically detect the start of a COMPRESS2
351stream, in either the sending or receiving direction.
Sean Middleditch892c5f12009-03-14 13:39:07 -0400352
353VI. TELNET PROXY UTILITY
354=====================================================================
355
356The telnet-proxy utility is a small application that serves both as
357a testbed for libtelnet and as a powerful debugging tool for TELNET
358servers and clients.
359
360To use telnet-proxy, you must first compile it using:
361
362 $ make
363
364If you do not have zlib installed and wish to disable MCCP2 support
365then you must first edit the Makefile and remove the -DHAVE_ZLIB and
366the -lz from the compile flags.
367
Sean Middleditchd88f1832009-03-15 01:06:17 -0400368To run telnet-proxy, you simply give it the server's host name or
369IP address, the server's port number, and the port number that
370telnet-proxy should listen on. For example, to connect to the server
371on mud.example.com port 7800 and to listen on port 5000, run:
Sean Middleditch892c5f12009-03-14 13:39:07 -0400372
Sean Middleditchd88f1832009-03-15 01:06:17 -0400373 $ ./telnet-proxy mud.example.com 7800 5000
Sean Middleditch892c5f12009-03-14 13:39:07 -0400374
375You can then connect to the host telnet-proxy is running on (e.g.
Sean Middleditchd88f1832009-03-15 01:06:17 -0400376127.0.0.1) on port 500 and you will automatically be proxied into
377mud.example.com.
Sean Middleditch892c5f12009-03-14 13:39:07 -0400378
379telnet-proxy will display status information about the data
Sean Middleditchaefcd0c2009-03-15 13:16:44 -0400380passing through both ends of the tunnel. telnet-proxy can only
381support a single tunnel at a time. It will continue running until
382an error occurs or a terminating signal is sent to the proxy
383process.