blob: 51156ae2b6d5c8f27fb1f5cf70bb54d1a55f185d [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
60 void libtelnet_init(struct libtelnet_t *telnet,
Sean Middleditch9f79cc52009-03-15 13:39:24 -040061 libtelnet_event_handler_t handler, enum libtelnet_mode_t mode,
62 void *user_data);
Sean Middleditch892c5f12009-03-14 13:39:07 -040063 The libtelnet_init() function is responsible for initializing
64 the data in a libtelnet_t structure. It must be called
65 immediately after establishing a connection and before any other
66 libtelnet API calls are made.
67
Sean Middleditch637df7f2009-03-15 12:57:32 -040068 The handler parameter must be a function matching the
69 libtelnet_event_handler_t definition. More information about
70 events can be found in section IId.
Sean Middleditch30323022009-03-14 21:45:28 -040071
Sean Middleditch9f79cc52009-03-15 13:39:24 -040072 The user_data parameter is passed to the event handler whenver it
73 is invoked. This will usually be a structure container
74 information about the connection, including a socket descriptor
75 for implementing LIBTELNET_EV_SEND event handling.
76
Sean Middleditchf66a7ee2009-03-15 11:54:07 -040077 The mode parameter must be one of LIBTELNET_MODE_SERVER,
78 LIBTELNET_MODE_CLIENT, or LIBTELNET_MODE_PROXY. These slightly
79 alter the behavior of libtelnet in certain instances. If you are
80 implementing a TELNET server, use the SERVER mode. If you are
81 implementing a client, use the CLIENT mode. The PROXY mode
82 enables special behavior for telnet-proxy (or similar
83 applications).
Sean Middleditch892c5f12009-03-14 13:39:07 -040084
85 boid libtelnet_free(struct libtelnet_t *telnet);
86 Releases any internal memory allocated by libtelnet. This must
87 be called whenever a connection is closed, or you will incur
88 memory leaks.
89
90IIb. Receiving Data
91
92 void libtelnet_push(struct libtelnet_t *telnet,
93 unsigned char *buffer, unsigned int size, void *user_data);
94 When your application receives data over the socket from the
95 remote end, it must pass the received bytes into this function.
Sean Middleditch637df7f2009-03-15 12:57:32 -040096
97 As the TELNET stream is parsed, events will be generated and
98 passed to the event handler given to libtelnet_init(). Of
99 particular interest for data receiving is the LIBTELNET_EV_DATA
100 event, which is triggered for any regular data such as user
101 input or server process output.
Sean Middleditch892c5f12009-03-14 13:39:07 -0400102
103IIc. Sending Data
104
Sean Middleditch637df7f2009-03-15 12:57:32 -0400105 All of the libtelnet_send_*() functions will invoke the
Sean Middleditch9f79cc52009-03-15 13:39:24 -0400106 LIBTELNET_EV_SEND event.
Sean Middleditch637df7f2009-03-15 12:57:32 -0400107
108 Note: it is very important that ALL data sent to the remote end of
109 the connection be passed through libtelnet. All user input or
110 process output that you wish to send over the wire should be given
111 to libtelnet_send_data(). Do NOT send or buffer unprocessed output
112 data directly!
Sean Middleditch892c5f12009-03-14 13:39:07 -0400113
114 void libtelnet_send_command(struct libtelnet_t *telnet,
Sean Middleditch9f79cc52009-03-15 13:39:24 -0400115 unsigned char cmd);
Sean Middleditch892c5f12009-03-14 13:39:07 -0400116 Sends a single "simple" TELNET command, such as the GO-AHEAD
117 commands (255 249).
118
119 void libtelnet_send_negotiate(struct libtelnet_t *telnet,
Sean Middleditch9f79cc52009-03-15 13:39:24 -0400120 unsigned char cmd, unsigned char opt);
Sean Middleditch892c5f12009-03-14 13:39:07 -0400121 Sends a TELNET negotiation command. The cmd parameter must be
122 one of LIBTELNET_WILL, LIBTELNET_DONT, LIBTELNET_DO, or
123 LIBTELNET_DONT. The opt parameter is the option to
124 negotiate.
125
126 void libtelnet_send_data(struct libtelnet_t *telnet,
Sean Middleditch9f79cc52009-03-15 13:39:24 -0400127 unsigned char *buffer, unsigned int size);
Sean Middleditch892c5f12009-03-14 13:39:07 -0400128 Sends raw data, which would be either the process output from
129 a server or the user input from a client.
130
131 void libtelnet_send_subnegotiation(struct libtelnet_t *telnet,
Sean Middleditch9f79cc52009-03-15 13:39:24 -0400132 unsigned char opt, unsigned char *buffer, unsigned int size);
Sean Middleditch892c5f12009-03-14 13:39:07 -0400133 Sends a TELNET sub-negotiation command. The opt parameter
134 is the sub-negotiation option.
135
Sean Middleditch637df7f2009-03-15 12:57:32 -0400136IId. Event Handling
Sean Middleditch892c5f12009-03-14 13:39:07 -0400137
Sean Middleditch637df7f2009-03-15 12:57:32 -0400138 libtelnet relies on an event-handling mechanism for processing
139 the parsed TELNET protocol stream as well as for buffering and
140 sending output data.
Sean Middleditch892c5f12009-03-14 13:39:07 -0400141
Sean Middleditch637df7f2009-03-15 12:57:32 -0400142 When you initialize a libtelnet_t structure with libtelnet_init()
143 you had to pass in an event handler function. This function must
144 meet the following prototype:
Sean Middleditch30323022009-03-14 21:45:28 -0400145
Sean Middleditch637df7f2009-03-15 12:57:32 -0400146 void (libtelnet_t *telnet, libtelnet_event_t *event,
Sean Middleditch9f79cc52009-03-15 13:39:24 -0400147 void *user_data);
148
149 The event structure is detailed below. The user_data value is the
150 pointer passed to libtelnet_init().
Sean Middleditch637df7f2009-03-15 12:57:32 -0400151
152 struct libtelnet_event_t {
153 enum libtelnet_event_type_t type;
154 unsigned char command;
155 unsigned char telopt;
156 unsigned char *buffer;
157 unsigned int size;
158 };
159
160 The enumeration values of libtelnet_event_type_t are described in
161 detail below. Whenever the the event handler is invoked, the
162 application must look at the event->type value and do any
163 necessary processing.
164
165 The only event that MUST be implemented is LIBTELNET_EV_SEND.
166 Most applications will also always want to implement the event
167 LIBTELNET_EV_DATA.
168
169 Here is an example event handler implementation which includes
170 handlers for several important events.
171
172 void my_event_handler(struct libtelnet_t *telnet,
173 libtelnet_event_t *ev, void *user_data) {
174 struct user_info *user = (struct user_info *)user_data;
175
176 switch (ev->type) {
177 case LIBTELNET_EV_DATA:
178 process_user_input(user, event->buffer, event->size);
179 break;
180 case LIBTELNET_EV_SEND:
181 write_to_descriptor(user, event->buffer, event->size);
182 break;
183 case LIBTELNET_EV_ERROR:
184 fatal_error("TELNET error: %s", event->buffer);
185 break;
186 }
Sean Middleditch30323022009-03-14 21:45:28 -0400187 }
188
Sean Middleditch637df7f2009-03-15 12:57:32 -0400189 LIBTELNET_EV_DATA:
190 The DATA event is triggered whenever regular data (not part of
191 any special TELNET command) is received. For a client, this
192 will be process output from the server. For a server, this will
193 be input typed by the user.
Sean Middleditch30323022009-03-14 21:45:28 -0400194
Sean Middleditch637df7f2009-03-15 12:57:32 -0400195 The event->buffer value will contain the bytes received and the
196 event->size value will contain the number of bytes received.
197 Note that event->buffer is not NUL terminated!
Sean Middleditch30323022009-03-14 21:45:28 -0400198
Sean Middleditch637df7f2009-03-15 12:57:32 -0400199 NOTE: there is no guarantee that user input or server output
200 will be received in whole lines. If you wish to process data
201 a line at a time, you are responsible for buffering the data and
202 checking for line terminators yourself!
203
204 LIBTELNET_EV_SEND:
205 This event is sent whenever libtelnet has generated data that
206 must be sent over the wire to the remove end. Generally that
207 means calling send() or adding the data to your application's
208 output buffer.
Sean Middleditch30323022009-03-14 21:45:28 -0400209
Sean Middleditch637df7f2009-03-15 12:57:32 -0400210 The event->buffer value will contain the bytes to send and the
211 event->size value will contain the number of bytes to send.
212 Note that event->buffer is not NUL terminated, and may include
213 NUL characters in its data, so always use event->size!
Sean Middleditch30323022009-03-14 21:45:28 -0400214
Sean Middleditch637df7f2009-03-15 12:57:32 -0400215 NOTE: Your SEND event handler must send or buffer the data in
216 its raw form as provided by libtelnet. If you wish to perform
217 any kind of preprocessing on data you want to send to the other
218
219 LIBTELNET_EV_IAC:
220 The IAC event is triggered whenever a simple IAC command is
221 received, such as the IAC EOR (end of record, also called
222 go ahead or GA) command.
Sean Middleditch892c5f12009-03-14 13:39:07 -0400223
Sean Middleditch637df7f2009-03-15 12:57:32 -0400224 The command received is in the event->command value.
Sean Middleditch892c5f12009-03-14 13:39:07 -0400225
Sean Middleditch637df7f2009-03-15 12:57:32 -0400226 The necessary processing depends on the specific commands; see
227 the TELNET RFC for more information.
228
Sean Middleditch5b5bc922009-03-15 23:02:10 -0400229 LIBTELNET_EV_WILL:
230 LIBTELNET_EV_DO:
231 The WILL and DO events are sent when a TELNET negotiation
232 command of the same name is received.
Sean Middleditch892c5f12009-03-14 13:39:07 -0400233
Sean Middleditch5b5bc922009-03-15 23:02:10 -0400234 WILL events are sent by the remote end when they wish to be
235 allowed to turn an option on on their end, or in confirmation
236 after you have sent a DO command to them.
Sean Middleditch892c5f12009-03-14 13:39:07 -0400237
Sean Middleditch5b5bc922009-03-15 23:02:10 -0400238 DO events are sent by the remote end when they wish for you
239 to turn on an option on your end, or in confirmation after you
240 have sent a WILL command to them.
241
242 In either case, the TELNET option under negotiation will be in
243 event->telopt field.
244
245 If you support the option and wish for it to be enabled you
246 must set the event->accept field to 1, unless this event is
247 a confirmation for a previous WILL/DO command you sent to the
248 remote end. If you do not set event->field to 1 then
249 libtelnet will send a rejection command back to the other end.
250
251 libtelnet manages some of the pecularities of negotiation for
252 you. For information on libtelnet's negotiation method, see:
Sean Middleditch892c5f12009-03-14 13:39:07 -0400253
254 http://www.faqs.org/rfcs/rfc1143.html
255
Sean Middleditch5b5bc922009-03-15 23:02:10 -0400256 Examples:
257
258 You want remote end to use TTYPE, so you send DO TTYPE.
259 Remote accepts and sends WILL TTYPE.
260
261 Remote end wants you to use SGA, so they send DO_SGA.
262 You do not support SGA and set event->accept = 0.
263
264 Remote end wants to use ZMP, so they send WILL ZMP.
265 You support ZMP, so you set event->accept = 1 and enable
266 local ZMP support.
267
268 You want to use MCCP2, so you send WILL COMPRESS2.
269 Remote end accepts and sends DO COMPRESS2.
270
271 Note that in PROXY mode libtelnet will do no processing of its
272 own for you.
273
274 LIBTELNET_EV_WONT:
275 LIBTELNET_EV_DONT:
276 The WONT and DONT events are sent when the remote end of the
277 connection wishes to disable an option, when they are
278 refusing to a support an option that you have asked for, or
279 in confirmation of an option you have asked to be disabled.
280
281 Most commonly WONT and DONT events are sent as rejections of
282 features you requested by sending DO or WILL events. Receiving
283 these events means the TELNET option is not or will not be
284 supported by the remote end, so give up.
285
286 Sometimes WONT or DONT will be sent for TELNET options that are
287 already enabled, but the remote end wishes to stop using. You
288 cannot decline. These events are demands that must be complied
289 with. libtelnet will always send the appropriate response back
290 without consulting your application. These events are sent to
291 allow your application to disable its own use of the features.
292
293 In either case, the TELNET option under negotiation will be in
294 event->telopt field.
295
296 Note that in PROXY mode libtelnet will do no processing of its
297 own for you.
298
Sean Middleditch637df7f2009-03-15 12:57:32 -0400299 LIBTELNET_EV_SUBNEGOTIATION:
300 Triggered whenever a TELNET sub-negotiation has been received.
Sean Middleditch892c5f12009-03-14 13:39:07 -0400301 Sub-negotiations include the NAWS option for communicating
302 terminal size to a server, the NEW-ENVIRON and TTYPE options
303 for negotiating terminal features, and MUD-centric protocols
304 such as ZMP, MSSP, and MCCP2.
305
Sean Middleditch637df7f2009-03-15 12:57:32 -0400306 The event->telopt value is the option under sub-negotiation.
307 The remaining data (if any) is passed in event->buffer and
308 event->size. Note that most subnegotiation commands can
309 include embedded NUL bytes in the subnegotiation data, and
310 the data event->buffer is not NUL terminated, so always use
311 the event->size value!
Sean Middleditch892c5f12009-03-14 13:39:07 -0400312
Sean Middleditch637df7f2009-03-15 12:57:32 -0400313 The meaning and necessary processing for subnegotiations are
314 defined in various TELNET RFCs and other informal
315 specifications. A subnegotiation should never be sent unless
316 the specific option has been enabled through the use of the
317 telnet negotiation feature.
Sean Middleditch892c5f12009-03-14 13:39:07 -0400318
Sean Middleditch637df7f2009-03-15 12:57:32 -0400319 LIBTELNET_EV_COMPRESS
320 The COMPRESS event notifies the app that COMPRESS2/MCCP2
321 compression has begun or ended. Only servers can send compressed
322 data, and hence only clients will receive compressed data.
Sean Middleditchb9e48642009-03-12 23:33:27 -0400323
Sean Middleditch637df7f2009-03-15 12:57:32 -0400324 The event->command value will be 1 if compression has started and
325 will be 0 if compression has ended.
Sean Middleditch16992272009-03-15 19:42:03 -0400326
327 LIBTELNET_EV_WARNING
328 The WARNING event is sent whenever something has gone wrong
329 inside of libtelnet (possibly due to malformed data sent by the
330 other end) but which recovery is (likely) possible. It may be
331 safe to continue using the connection, but some data may have
332 been lost or incorrectly interpreted.
Sean Middleditch637df7f2009-03-15 12:57:32 -0400333
334 The event->buffer value will contain a NUL terminated string
335 explaining the error, and the event->size value containers the
336 length of the string.
337
Sean Middleditch16992272009-03-15 19:42:03 -0400338 LIBTELNET_EV_ERROR
339 Similar to the WARNING event, the ERROR event is sent whenever
340 something has gone wrong. ERROR events are non-recoverable,
341 however, and the application should immediately close the
342 connection. Whatever has happened is likely going only to
343 result in garbage from libtelnet. This is most likely to
344 happen when a COMPRESS2 stream fails, but other problems can
345 occur.
346
347 The event->buffer value will contain a NUL terminated string
348 explaining the error, and the event->size value containers the
349 length of the string.
Sean Middleditch637df7f2009-03-15 12:57:32 -0400350
351III. INTEGRATING LIBTELNET WITH COMMON MUDS
Sean Middleditchb9e48642009-03-12 23:33:27 -0400352=====================================================================
353
Sean Middleditch637df7f2009-03-15 12:57:32 -0400354FIXME: fill in some notes about how to splice in libtelnet with
355common Diku/Merc/Circle/etc. MUD codebases.
Sean Middleditchb9e48642009-03-12 23:33:27 -0400356
Sean Middleditch892c5f12009-03-14 13:39:07 -0400357IV. SAFETY AND CORRECTNESS CONSIDERATIONS
Sean Middleditchb9e48642009-03-12 23:33:27 -0400358=====================================================================
359
Sean Middleditch892c5f12009-03-14 13:39:07 -0400360Your existing application may make heavy use of its own output
361buffering and transmission commands, including hand-made routines
362for sending TELNET commands and sub-negotiation requests. There are
363at times subtle issues that need to be handled when communication
364over the TELNET protocol, not least of which is the need to escape
365any byte value 0xFF with a special TELNET command.
Sean Middleditchb9e48642009-03-12 23:33:27 -0400366
Sean Middleditch892c5f12009-03-14 13:39:07 -0400367For these reasons, it is very important that applications making use
368of libtelnet always make use of the libtelnet_send_*() family of
369functions for all data being sent over the TELNET connection.
370
Sean Middleditch637df7f2009-03-15 12:57:32 -0400371In particular, if you are writing a client, all user input must be
372passed through to libtelnet_send_data(). This also includes any
373input generated automatically by scripts, triggers, or macros.
374
375For a server, any and all output -- including ANSI/VT100 escape
376codes, regular text, newlines, and so on -- must be passed through
377to libtelnet_send_data().
378
379Any TELNET commands that are to be sent must be given to one of the
380following: libtelnet_send_command, libtelnet_send_negotiate, or
381libtelnet_send_subnegotiation().
382
383If you are attempting to enable COMPRESS2/MCCP2, you must use the
384libtelnet_begin_compress2() function.
385
Sean Middleditch892c5f12009-03-14 13:39:07 -0400386V. MCCP2 COMPRESSION
Sean Middleditchb9e48642009-03-12 23:33:27 -0400387=====================================================================
388
Sean Middleditch892c5f12009-03-14 13:39:07 -0400389The MCCP2 (COMPRESS2) TELNET extension allows for the compression of
390all traffic sent from server to client. For more information:
391
392 http://www.mudbytes.net/index.php?a=articles&s=mccp
393
Sean Middleditch637df7f2009-03-15 12:57:32 -0400394In order for libtelnet to support MCCP2, zlib must be installed and
395enabled when compiling libtelnet. Use -DHAVE_ZLIB to enable zlib
396when compiling libtelnet.c and pass -lz to the linker to link in the
397zlib shared library.
398
Sean Middleditch892c5f12009-03-14 13:39:07 -0400399libtelnet transparently supports MCCP2. For a server to support
400MCCP2, the application must begin negotiation of the COMPRESS2
401option using libtelnet_send_negotiate(), for example:
402
403 libtelnet_send_negotiate(&telnet, LIBTELNET_WILL,
404 LIBTELNET_OPTION_COMPRESS2, user_data);
405
Sean Middleditch5b5bc922009-03-15 23:02:10 -0400406If a favorable DO COMPRESS2 is sent back from the client then the
407server application can begin compression at any time by calling
408libtelnet_begin_compress2().
Sean Middleditch892c5f12009-03-14 13:39:07 -0400409
Sean Middleditch637df7f2009-03-15 12:57:32 -0400410If a connection is in PROXY mode and COMPRESS2 support is enabled
411then libtelnet will automatically detect the start of a COMPRESS2
412stream, in either the sending or receiving direction.
Sean Middleditch892c5f12009-03-14 13:39:07 -0400413
414VI. TELNET PROXY UTILITY
415=====================================================================
416
417The telnet-proxy utility is a small application that serves both as
418a testbed for libtelnet and as a powerful debugging tool for TELNET
419servers and clients.
420
421To use telnet-proxy, you must first compile it using:
422
423 $ make
424
425If you do not have zlib installed and wish to disable MCCP2 support
426then you must first edit the Makefile and remove the -DHAVE_ZLIB and
427the -lz from the compile flags.
428
Sean Middleditchd88f1832009-03-15 01:06:17 -0400429To run telnet-proxy, you simply give it the server's host name or
430IP address, the server's port number, and the port number that
431telnet-proxy should listen on. For example, to connect to the server
432on mud.example.com port 7800 and to listen on port 5000, run:
Sean Middleditch892c5f12009-03-14 13:39:07 -0400433
Sean Middleditchd88f1832009-03-15 01:06:17 -0400434 $ ./telnet-proxy mud.example.com 7800 5000
Sean Middleditch892c5f12009-03-14 13:39:07 -0400435
436You can then connect to the host telnet-proxy is running on (e.g.
Sean Middleditchd88f1832009-03-15 01:06:17 -0400437127.0.0.1) on port 500 and you will automatically be proxied into
438mud.example.com.
Sean Middleditch892c5f12009-03-14 13:39:07 -0400439
440telnet-proxy will display status information about the data
Sean Middleditchaefcd0c2009-03-15 13:16:44 -0400441passing through both ends of the tunnel. telnet-proxy can only
442support a single tunnel at a time. It will continue running until
443an error occurs or a terminating signal is sent to the proxy
444process.