1 |
/* |
/* Copyright (C) 1998,2001 Free Software Foundation, Inc. |
2 |
* Copyright (c) 1989, 1993 |
|
3 |
* The Regents of the University of California. All rights reserved. |
This file is part of GNU Inetutils. |
4 |
* |
|
5 |
* Redistribution and use in source and binary forms, with or without |
GNU Inetutils is free software; you can redistribute it and/or modify |
6 |
* modification, are permitted provided that the following conditions |
it under the terms of the GNU General Public License as published by |
7 |
* are met: |
the Free Software Foundation; either version 2, or (at your option) |
8 |
* 1. Redistributions of source code must retain the above copyright |
any later version. |
9 |
* notice, this list of conditions and the following disclaimer. |
|
10 |
* 2. Redistributions in binary form must reproduce the above copyright |
GNU Inetutils is distributed in the hope that it will be useful, |
11 |
* notice, this list of conditions and the following disclaimer in the |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 |
* documentation and/or other materials provided with the distribution. |
MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the |
13 |
* 4. Neither the name of the University nor the names of its contributors |
GNU General Public License for more details. |
14 |
* may be used to endorse or promote products derived from this software |
|
15 |
* without specific prior written permission. |
You should have received a copy of the GNU General Public License |
16 |
* |
along with GNU Inetutils; see the file COPYING. If not, write to |
17 |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
18 |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
Boston, MA 02111-1307, USA. */ |
19 |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
20 |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
#ifdef HAVE_CONFIG_H |
21 |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
# include <config.h> |
22 |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
#endif |
23 |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
#include <sys/types.h> |
24 |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
#include <sys/time.h> |
25 |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
#include <stdio.h> |
26 |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
#include <stdlib.h> |
27 |
* SUCH DAMAGE. |
#include <sys/socket.h> |
28 |
* |
#include <netinet/in.h> |
29 |
* @(#)telnetd.h 8.1 (Berkeley) 6/4/93 |
#include <netdb.h> |
30 |
*/ |
#include <unistd.h> |
31 |
|
#include <signal.h> |
32 |
/* Assume that is HAVE_PTSNAME is set we can use SYSVR4 pseudo tty facility */ |
#include <errno.h> |
33 |
#ifdef HAVE_PTSNAME |
#include <syslog.h> |
34 |
# define STREAMSPTY |
#include <string.h> |
35 |
|
#ifdef HAVE_STRINGS_H |
36 |
|
# include <strings.h> |
37 |
|
#endif |
38 |
|
#ifdef HAVE_SYS_FILIO_H |
39 |
|
# include <sys/filio.h> |
40 |
|
#endif |
41 |
|
#ifdef HAVE_SYS_TTY_H |
42 |
|
# include <sys/tty.h> |
43 |
|
#endif |
44 |
|
#ifdef HAVE_SYS_PTYVAR_H |
45 |
|
# include <sys/ptyvar.h> |
46 |
#endif |
#endif |
47 |
|
#ifdef HAVE_STROPTS_H |
48 |
|
# include <stropts.h> |
49 |
|
#endif |
50 |
|
#include <sys/ioctl.h> |
51 |
|
|
52 |
|
#include <arpa/telnet.h> |
53 |
|
#include <libtelnet/auth.h> |
54 |
|
|
55 |
#include "defs.h" |
#ifndef P |
56 |
#include "ext.h" |
# if defined PROTOTYPES || (defined __STDC__ && __STDC__) |
57 |
|
# define P(x) x |
58 |
|
# else |
59 |
|
# define P(x) () |
60 |
|
# endif |
61 |
|
#endif |
62 |
|
|
63 |
#ifdef DIAGNOSTICS |
#if defined(HAVE_TERMIOS_H) |
64 |
#define DIAG(a,b) if (diagnostic & (a)) b |
# include <termios.h> |
65 |
|
#elif defined(HAVE_TERMIO_H) |
66 |
|
# include <termio.h> |
67 |
#else |
#else |
68 |
#define DIAG(a,b) |
# include <sgtty.h> |
69 |
|
#endif |
70 |
|
|
71 |
|
#define obstack_chunk_alloc malloc |
72 |
|
#define obstack_chunk_free free |
73 |
|
#include <obstack.h> |
74 |
|
|
75 |
|
#ifndef HAVE_CC_T |
76 |
|
typedef unsigned char cc_t; |
77 |
|
#endif |
78 |
|
|
79 |
|
typedef enum debug_mode |
80 |
|
{ |
81 |
|
debug_options, |
82 |
|
debug_report, |
83 |
|
debug_net_data, |
84 |
|
debug_pty_data, |
85 |
|
debug_auth, |
86 |
|
debug_max_mode |
87 |
|
} debug_mode_t; |
88 |
|
|
89 |
|
#define MAX_DEBUG_LEVEL 100 |
90 |
|
|
91 |
|
extern int debug_level[]; |
92 |
|
|
93 |
|
#define DEBUG(mode,level,c) if (debug_level[mode]>=level) c |
94 |
|
|
95 |
|
struct telnetd_clocks |
96 |
|
{ |
97 |
|
int system; /* what the current time is */ |
98 |
|
int echotoggle; /* last time user entered echo character */ |
99 |
|
int modenegotiated; /* last time operating mode negotiated */ |
100 |
|
int didnetreceive; /* last time we read data from network */ |
101 |
|
int ttypesubopt; /* ttype subopt is received */ |
102 |
|
int tspeedsubopt; /* tspeed subopt is received */ |
103 |
|
int environsubopt; /* environ subopt is received */ |
104 |
|
int oenvironsubopt; /* old environ subopt is received */ |
105 |
|
int xdisplocsubopt; /* xdisploc subopt is received */ |
106 |
|
int baseline; /* time started to do timed action */ |
107 |
|
int gotDM; /* when did we last see a data mark */ |
108 |
|
}; |
109 |
|
#define settimer(x) (clocks.x = ++clocks.system) |
110 |
|
#define sequenceIs(x,y) (clocks.x < clocks.y) |
111 |
|
|
112 |
|
/* |
113 |
|
* Structures of information for each special character function. |
114 |
|
*/ |
115 |
|
typedef struct |
116 |
|
{ |
117 |
|
unsigned char flag; /* the flags for this function */ |
118 |
|
cc_t val; /* the value of the special character */ |
119 |
|
} slcent, *Slcent; |
120 |
|
|
121 |
|
typedef struct |
122 |
|
{ |
123 |
|
slcent defset; /* the default settings */ |
124 |
|
slcent current; /* the current settings */ |
125 |
|
cc_t *sptr; /* a pointer to the char in */ |
126 |
|
/* system data structures */ |
127 |
|
} slcfun, *Slcfun; |
128 |
|
|
129 |
|
#ifdef HAVE_UNAME |
130 |
|
/* Prefix and suffix if the IM string can be generated from uname. */ |
131 |
|
# define UNAME_IM_PREFIX "\r\n" |
132 |
|
# define UNAME_IM_SUFFIX " (%h) (%t)\r\n\n" |
133 |
|
#else /* ! HAVE_UNAME */ |
134 |
|
# define UNAME_IM_PREFIX "\r\n" |
135 |
|
# define UNAME_IM_SUFFIX "\r\n" |
136 |
|
#endif |
137 |
|
|
138 |
|
/* ********************* */ |
139 |
|
/* State machine */ |
140 |
|
/* |
141 |
|
* We keep track of each side of the option negotiation. |
142 |
|
*/ |
143 |
|
|
144 |
|
#define MY_STATE_WILL 0x01 |
145 |
|
#define MY_WANT_STATE_WILL 0x02 |
146 |
|
#define MY_STATE_DO 0x04 |
147 |
|
#define MY_WANT_STATE_DO 0x08 |
148 |
|
|
149 |
|
/* |
150 |
|
* Macros to check the current state of things |
151 |
|
*/ |
152 |
|
|
153 |
|
#define my_state_is_do(opt) (options[opt]&MY_STATE_DO) |
154 |
|
#define my_state_is_will(opt) (options[opt]&MY_STATE_WILL) |
155 |
|
#define my_want_state_is_do(opt) (options[opt]&MY_WANT_STATE_DO) |
156 |
|
#define my_want_state_is_will(opt) (options[opt]&MY_WANT_STATE_WILL) |
157 |
|
|
158 |
|
#define my_state_is_dont(opt) (!my_state_is_do(opt)) |
159 |
|
#define my_state_is_wont(opt) (!my_state_is_will(opt)) |
160 |
|
#define my_want_state_is_dont(opt) (!my_want_state_is_do(opt)) |
161 |
|
#define my_want_state_is_wont(opt) (!my_want_state_is_will(opt)) |
162 |
|
|
163 |
|
#define set_my_state_do(opt) (options[opt] |= MY_STATE_DO) |
164 |
|
#define set_my_state_will(opt) (options[opt] |= MY_STATE_WILL) |
165 |
|
#define set_my_want_state_do(opt) (options[opt] |= MY_WANT_STATE_DO) |
166 |
|
#define set_my_want_state_will(opt) (options[opt] |= MY_WANT_STATE_WILL) |
167 |
|
|
168 |
|
#define set_my_state_dont(opt) (options[opt] &= ~MY_STATE_DO) |
169 |
|
#define set_my_state_wont(opt) (options[opt] &= ~MY_STATE_WILL) |
170 |
|
#define set_my_want_state_dont(opt) (options[opt] &= ~MY_WANT_STATE_DO) |
171 |
|
#define set_my_want_state_wont(opt) (options[opt] &= ~MY_WANT_STATE_WILL) |
172 |
|
|
173 |
|
/* |
174 |
|
* Tricky code here. What we want to know is if the MY_STATE_WILL |
175 |
|
* and MY_WANT_STATE_WILL bits have the same value. Since the two |
176 |
|
* bits are adjacent, a little arithmatic will show that by adding |
177 |
|
* in the lower bit, the upper bit will be set if the two bits were |
178 |
|
* different, and clear if they were the same. |
179 |
|
*/ |
180 |
|
#define my_will_wont_is_changing(opt) \ |
181 |
|
((options[opt]+MY_STATE_WILL) & MY_WANT_STATE_WILL) |
182 |
|
|
183 |
|
#define my_do_dont_is_changing(opt) \ |
184 |
|
((options[opt]+MY_STATE_DO) & MY_WANT_STATE_DO) |
185 |
|
|
186 |
|
/* |
187 |
|
* Make everything symetrical |
188 |
|
*/ |
189 |
|
|
190 |
|
#define HIS_STATE_WILL MY_STATE_DO |
191 |
|
#define HIS_WANT_STATE_WILL MY_WANT_STATE_DO |
192 |
|
#define HIS_STATE_DO MY_STATE_WILL |
193 |
|
#define HIS_WANT_STATE_DO MY_WANT_STATE_WILL |
194 |
|
|
195 |
|
#define his_state_is_do my_state_is_will |
196 |
|
#define his_state_is_will my_state_is_do |
197 |
|
#define his_want_state_is_do my_want_state_is_will |
198 |
|
#define his_want_state_is_will my_want_state_is_do |
199 |
|
|
200 |
|
#define his_state_is_dont my_state_is_wont |
201 |
|
#define his_state_is_wont my_state_is_dont |
202 |
|
#define his_want_state_is_dont my_want_state_is_wont |
203 |
|
#define his_want_state_is_wont my_want_state_is_dont |
204 |
|
|
205 |
|
#define set_his_state_do set_my_state_will |
206 |
|
#define set_his_state_will set_my_state_do |
207 |
|
#define set_his_want_state_do set_my_want_state_will |
208 |
|
#define set_his_want_state_will set_my_want_state_do |
209 |
|
|
210 |
|
#define set_his_state_dont set_my_state_wont |
211 |
|
#define set_his_state_wont set_my_state_dont |
212 |
|
#define set_his_want_state_dont set_my_want_state_wont |
213 |
|
#define set_his_want_state_wont set_my_want_state_dont |
214 |
|
|
215 |
|
#define his_will_wont_is_changing my_do_dont_is_changing |
216 |
|
#define his_do_dont_is_changing my_will_wont_is_changing |
217 |
|
|
218 |
|
/* ******* */ |
219 |
|
|
220 |
|
void fatal (int f, char *msg); |
221 |
|
|
222 |
|
/* |
223 |
|
* Linemode support states, in decreasing order of importance |
224 |
|
*/ |
225 |
|
#define REAL_LINEMODE 0x04 |
226 |
|
#define KLUDGE_OK 0x03 |
227 |
|
#define NO_AUTOKLUDGE 0x02 |
228 |
|
#define KLUDGE_LINEMODE 0x01 |
229 |
|
#define NO_LINEMODE 0x00 |
230 |
|
|
231 |
|
#include <arpa/telnet.h> |
232 |
|
|
233 |
|
#define NETSLOP 64 |
234 |
|
|
235 |
|
#define ttloop(c) while (c) io_drain () |
236 |
|
|
237 |
|
/* External variables */ |
238 |
|
extern char options[256]; |
239 |
|
extern char do_dont_resp[256]; |
240 |
|
extern char will_wont_resp[256]; |
241 |
|
extern int linemode; /* linemode on/off */ |
242 |
|
extern int uselinemode; /* what linemode to use (on/off) */ |
243 |
|
extern int editmode; /* edit modes in use */ |
244 |
|
extern int useeditmode; /* edit modes to use */ |
245 |
|
extern int alwayslinemode; /* command line option */ |
246 |
|
extern int lmodetype; /* Client support for linemode */ |
247 |
|
extern int flowmode; /* current flow control state */ |
248 |
|
extern int restartany; /* restart output on any character state */ |
249 |
|
extern int diagnostic; /* telnet diagnostic capabilities */ |
250 |
|
#if defined(AUTHENTICATION) |
251 |
|
extern int auth_level; |
252 |
#endif |
#endif |
253 |
|
|
254 |
/* other external variables */ |
extern slcfun slctab[NSLC + 1]; /* slc mapping table */ |
255 |
extern char **environ; |
|
256 |
extern int errno; |
extern char *terminaltype; |
257 |
|
|
258 |
|
extern int pty, net; |
259 |
|
extern int SYNCHing; /* we are in TELNET SYNCH mode */ |
260 |
|
extern struct telnetd_clocks clocks; |
261 |
|
extern char line[]; |
262 |
|
|
263 |
|
void io_setup P((void)); |
264 |
|
int net_has_data P((void)); |
265 |
|
int net_get_char P((int peek)); |
266 |
|
void set_neturg P((void)); |
267 |
|
int net_output_data P((const char *format,...)); |
268 |
|
int net_output_datalen P((const void *buf, size_t l)); |
269 |
|
int net_buffer_level P((void)); |
270 |
|
void io_drain P((void)); |
271 |
|
|
272 |
|
int stilloob P((int s)); |
273 |
|
void ptyflush P((void)); |
274 |
|
char * nextitem P((char *current)); |
275 |
|
void netclear P(()); |
276 |
|
void netflush P(()); |
277 |
|
|
278 |
|
int pty_buffer_is_full P((void)); |
279 |
|
void pty_output_byte P((int c)); |
280 |
|
void pty_output_datalen P((const void *data, size_t len)); |
281 |
|
int pty_buffer_level P(()); |
282 |
|
|
283 |
|
/* Debugging functions */ |
284 |
|
extern void printoption P((char *, int)); |
285 |
|
extern void printdata P((char *, char *, int)); |
286 |
|
extern void printsub P((int, unsigned char *, int)); |
287 |
|
extern void debug_output_datalen P((const char *data, size_t len)); |
288 |
|
extern void debug_output_data P((const char *fmt, ...)); |
289 |
|
|
290 |
|
/* TTY functions */ |
291 |
|
extern void init_termbuf P((void)); |
292 |
|
extern void set_termbuf P((void)); |
293 |
|
extern int spcset P((int func, cc_t *valp, cc_t **valpp)); |
294 |
|
extern void term_send_eof P((void)); |
295 |
|
extern int term_change_eof P((void)); |
296 |
|
|
297 |
|
extern void tty_binaryin P((int)); |
298 |
|
extern void tty_binaryout P((int)); |
299 |
|
extern int tty_flowmode P((void)); |
300 |
|
extern int tty_restartany P((void)); |
301 |
|
extern int tty_isbinaryin P((void)); |
302 |
|
extern int tty_isbinaryout P((void)); |
303 |
|
extern int tty_iscrnl P((void)); |
304 |
|
extern int tty_isecho P((void)); |
305 |
|
extern int tty_isediting P((void)); |
306 |
|
extern int tty_islitecho P((void)); |
307 |
|
extern int tty_isnewmap P((void)); |
308 |
|
extern int tty_israw P((void)); |
309 |
|
extern int tty_issofttab P((void)); |
310 |
|
extern int tty_istrapsig P((void)); |
311 |
|
extern int tty_linemode P((void)); |
312 |
|
extern void tty_rspeed P((int)); |
313 |
|
extern void tty_setecho P((int)); |
314 |
|
extern void tty_setedit P((int)); |
315 |
|
extern void tty_setlinemode P((int)); |
316 |
|
extern void tty_setlitecho P((int)); |
317 |
|
extern void tty_setsig P((int)); |
318 |
|
extern void tty_setsofttab P((int)); |
319 |
|
extern void tty_tspeed P((int)); |
320 |
|
|
321 |
|
/* FIXME */ |
322 |
|
extern void _termstat P((void)); |
323 |
|
extern void add_slc P((char func, char flag, cc_t val)); |
324 |
|
extern void check_slc P((void)); |
325 |
|
extern void change_slc P((char func, char flag, cc_t val)); |
326 |
|
|
327 |
|
extern void cleanup P((int)); |
328 |
|
extern void clientstat P((int, int, int)); |
329 |
|
extern void copy_termbuf P(()); |
330 |
|
extern void deferslc P((void)); |
331 |
|
extern void defer_terminit P((void)); |
332 |
|
extern void do_opt_slc P((unsigned char *, int)); |
333 |
|
extern void dooption P((int)); |
334 |
|
extern void dontoption P((int)); |
335 |
|
extern void edithost P((char *, char *)); |
336 |
|
extern void fatal P((int, char *)); |
337 |
|
extern void fatalperror P((int, char *)); |
338 |
|
extern void get_slc_defaults P((void)); |
339 |
|
extern void localstat P((void)); |
340 |
|
extern void flowstat P((void)); |
341 |
|
extern void netclear P((void)); |
342 |
|
|
343 |
|
extern void send_do P((int, int)); |
344 |
|
extern void send_dont P((int, int)); |
345 |
|
extern void send_slc P((void)); |
346 |
|
extern void send_status P((void)); |
347 |
|
extern void send_will P((int, int)); |
348 |
|
extern void send_wont P((int, int)); |
349 |
|
extern void set_termbuf P((void)); |
350 |
|
extern void start_login P((char *, int, char *)); |
351 |
|
extern void start_slc P((int)); |
352 |
|
extern void start_slave P((char *, int, char *)); |
353 |
|
|
354 |
|
extern void suboption P((void)); |
355 |
|
extern void telrcv P((void)); |
356 |
|
extern void ttloop P((void)); |
357 |
|
|
358 |
|
extern int end_slc P((unsigned char **)); |
359 |
|
extern int spcset P((int, cc_t *, cc_t **)); |
360 |
|
extern int stilloob P((int)); |
361 |
|
extern int terminit P((void)); |
362 |
|
extern int termstat P((void)); |
363 |
|
extern void willoption P((int)); |
364 |
|
extern void wontoption P((int)); |
365 |
|
|
366 |
|
#ifdef ENCRYPTION |
367 |
|
extern void (*encrypt_output) P((unsigned char *, int)); |
368 |
|
extern int (*decrypt_input) P((int)); |
369 |
|
extern char *nclearto; |
370 |
|
#endif /* ENCRYPTION */ |
371 |
|
|
372 |
|
|
373 |
|
|
374 |
|
|
375 |
|
|