xref: /freebsd/contrib/telnet/telnet/main.c (revision 1719886f6d08408b834d270c59ffcfd821c8f63a)
1 /*
2  * Copyright (c) 1988, 1990, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the University nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 
30 #if 0
31 #ifndef lint
32 static const char sccsid[] = "@(#)main.c	8.3 (Berkeley) 5/30/95";
33 #endif
34 #endif
35 
36 #include <sys/param.h>
37 #include <sys/socket.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <unistd.h>
41 
42 #include "ring.h"
43 #include "externs.h"
44 #include "defines.h"
45 
46 #ifdef	AUTHENTICATION
47 #include <libtelnet/auth.h>
48 #endif
49 #ifdef	ENCRYPTION
50 #include <libtelnet/encrypt.h>
51 #endif
52 
53 /* These values need to be the same as defined in libtelnet/kerberos5.c */
54 /* Either define them in both places, or put in some common header file. */
55 #define OPTS_FORWARD_CREDS	0x00000002
56 #define OPTS_FORWARDABLE_CREDS	0x00000001
57 
58 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
59 char *ipsec_policy_in = NULL;
60 char *ipsec_policy_out = NULL;
61 #endif
62 
63 extern int tos;
64 extern int quiet_mode;
65 
66 int family = AF_UNSPEC;
67 
68 /*
69  * Initialize variables.
70  */
71 void
72 tninit(void)
73 {
74     init_terminal();
75 
76     init_network();
77 
78     init_telnet();
79 
80     init_sys();
81 }
82 
83 static void
84 usage(void)
85 {
86 	fprintf(stderr, "usage: %s %s%s%s%s\n",
87 	    prompt,
88 #ifdef	AUTHENTICATION
89 	    "[-4] [-6] [-8] [-B baudrate] [-E] [-K] [-L] [-N] [-S tos] [-X atype]",
90 	    "\n\t[-c] [-d] [-e char] [-k realm] [-l user] [-f/-F] [-n tracefile] ",
91 #else
92 	    "[-4] [-6] [-8] [-B baudrate] [-E] [-L] [-N] [-S tos] [-c] [-d]",
93 	    "\n\t[-e char] [-l user] [-n tracefile] ",
94 #endif
95 	    "[-r] [-s src_addr] [-u] ",
96 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
97 	    "[-P policy] "
98 #endif
99 #ifdef	ENCRYPTION
100 	    "[-y] [host-name [port]]"
101 #else	/* ENCRYPTION */
102 	    "[host-name [port]]"
103 #endif	/* ENCRYPTION */
104 	);
105 	exit(1);
106 }
107 
108 /*
109  * main.  Parse arguments, invoke the protocol or command parser.
110  */
111 
112 int
113 main(int argc, char *argv[])
114 {
115 	u_long ultmp;
116 	int ch;
117 	char *ep, *user;
118 	char *src_addr = NULL;
119 #ifdef	FORWARD
120 	extern int forward_flags;
121 #endif	/* FORWARD */
122 
123 	setbuf(stdout, NULL);
124 	setbuf(stderr, NULL);
125 	tninit();		/* Clear out things */
126 
127 	TerminalSaveState();
128 
129 	if ((prompt = strrchr(argv[0], '/')))
130 		++prompt;
131 	else
132 		prompt = argv[0];
133 
134 	user = NULL;
135 
136 	rlogin = (strncmp(prompt, "rlog", 4) == 0) ? '~' : _POSIX_VDISABLE;
137 #ifdef AUTHENTICATION
138 	autologin = 1;
139 #else
140 	autologin = -1;
141 #endif
142 
143 #ifdef	ENCRYPTION
144 	encrypt_auto(1);
145 	decrypt_auto(1);
146 #endif
147 
148 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
149 #define IPSECOPT	"P:"
150 #else
151 #define IPSECOPT
152 #endif
153 	while ((ch = getopt(argc, argv,
154 			    "468B:EKLNQS:X:acde:fFk:l:n:rs:uxy" IPSECOPT)) != -1)
155 #undef IPSECOPT
156 	{
157 		switch(ch) {
158 		case '4':
159 			family = AF_INET;
160 			break;
161 #ifdef INET6
162 		case '6':
163 			family = AF_INET6;
164 			break;
165 #endif
166 		case '8':
167 			eight = 3;	/* binary output and input */
168 			break;
169 		case 'B':
170 			DoBaudRate(optarg);
171 			break;
172 		case 'E':
173 			rlogin = escape = _POSIX_VDISABLE;
174 			break;
175 		case 'K':
176 #ifdef	AUTHENTICATION
177 			autologin = 0;
178 #endif
179 			break;
180 		case 'L':
181 			eight |= 2;	/* binary output only */
182 			break;
183 		case 'N':
184 			doaddrlookup = 0;
185 			break;
186 		case 'Q':
187 			quiet_mode = 1;
188 			break;
189 		case 'S':
190 #ifdef	HAS_GETTOS
191 
192 			if ((tos = parsetos(optarg, "tcp")) < 0)
193 				fprintf(stderr, "%s%s%s%s\n",
194 					prompt, ": Bad TOS argument '",
195 					optarg,
196 					"; will try to use default TOS");
197 #else
198 #define	MAXTOS	255
199 			ultmp = strtoul(optarg, &ep, 0);
200 			if (*ep || ep == optarg || ultmp > MAXTOS)
201 				fprintf(stderr, "%s%s%s%s\n",
202 					prompt, ": Bad TOS argument '",
203 					optarg,
204 					"; will try to use default TOS");
205 			else
206 				tos = ultmp;
207 #endif
208 			break;
209 		case 'X':
210 #ifdef	AUTHENTICATION
211 			auth_disable_name(optarg);
212 #endif
213 			break;
214 		case 'a':
215 #ifdef	AUTHENTICATION
216 			/* It's the default now, so ignore */
217 #else
218 			autologin = 1;
219 #endif
220 			break;
221 		case 'c':
222 			skiprc = 1;
223 			break;
224 		case 'd':
225 			telnet_debug = 1;
226 			break;
227 		case 'e':
228 			set_escape_char(optarg);
229 			break;
230 		case 'f':
231 #ifdef	AUTHENTICATION
232 #if defined(KRB5) && defined(FORWARD)
233 			if (forward_flags & OPTS_FORWARD_CREDS) {
234 			    fprintf(stderr,
235 				    "%s: Only one of -f and -F allowed.\n",
236 				    prompt);
237 			    usage();
238 			}
239 			forward_flags |= OPTS_FORWARD_CREDS;
240 #else
241 			fprintf(stderr,
242 			 "%s: Warning: -f ignored, no Kerberos V5 support.\n",
243 				prompt);
244 #endif
245 #else
246 			fprintf(stderr,
247 			 "%s: Warning: -f ignored, no Kerberos V5 support.\n",
248 				prompt);
249 #endif
250 			break;
251 		case 'F':
252 #ifdef	AUTHENTICATION
253 #if defined(KRB5) && defined(FORWARD)
254 			if (forward_flags & OPTS_FORWARD_CREDS) {
255 			    fprintf(stderr,
256 				    "%s: Only one of -f and -F allowed.\n",
257 				    prompt);
258 			    usage();
259 			}
260 			forward_flags |= OPTS_FORWARD_CREDS;
261 			forward_flags |= OPTS_FORWARDABLE_CREDS;
262 #else
263 			fprintf(stderr,
264 			 "%s: Warning: -F ignored, no Kerberos V5 support.\n",
265 				prompt);
266 #endif
267 #else
268 			fprintf(stderr,
269 			 "%s: Warning: -F ignored, no Kerberos V5 support.\n",
270 				prompt);
271 #endif
272 			break;
273 		case 'k':
274 #ifdef	AUTHENTICATION
275 #if defined(KRB4)
276 		    {
277 			extern char *dest_realm, dst_realm_buf[], dst_realm_sz;
278 			dest_realm = dst_realm_buf;
279 			(void)strncpy(dest_realm, optarg, dst_realm_sz);
280 		    }
281 #else
282 			fprintf(stderr,
283 			   "%s: Warning: -k ignored, no Kerberos V4 support.\n",
284 								prompt);
285 #endif
286 #else
287 			fprintf(stderr,
288 			   "%s: Warning: -k ignored, no Kerberos V4 support.\n",
289 								prompt);
290 #endif
291 			break;
292 		case 'l':
293 #ifdef	AUTHENTICATION
294 			/* This is the default now, so ignore it */
295 #else
296 			autologin = 1;
297 #endif
298 			user = optarg;
299 			break;
300 		case 'n':
301 				SetNetTrace(optarg);
302 			break;
303 		case 'r':
304 			rlogin = '~';
305 			break;
306 		case 's':
307 			src_addr = optarg;
308 			break;
309 		case 'u':
310 			family = AF_UNIX;
311 			break;
312 		case 'x':
313 #ifndef	ENCRYPTION
314 			fprintf(stderr,
315 			    "%s: Warning: -x ignored, no ENCRYPT support.\n",
316 								prompt);
317 #endif	/* ENCRYPTION */
318 			break;
319 		case 'y':
320 #ifdef	ENCRYPTION
321 			encrypt_auto(0);
322 			decrypt_auto(0);
323 #else
324 			fprintf(stderr,
325 			    "%s: Warning: -y ignored, no ENCRYPT support.\n",
326 								prompt);
327 #endif	/* ENCRYPTION */
328 			break;
329 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
330 		case 'P':
331 			if (!strncmp("in", optarg, 2))
332 				ipsec_policy_in = strdup(optarg);
333 			else if (!strncmp("out", optarg, 3))
334 				ipsec_policy_out = strdup(optarg);
335 			else
336 				usage();
337 			break;
338 #endif
339 		case '?':
340 		default:
341 			usage();
342 			/* NOTREACHED */
343 		}
344 	}
345 	if (autologin == -1)
346 		autologin = (rlogin == _POSIX_VDISABLE) ? 0 : 1;
347 
348 	argc -= optind;
349 	argv += optind;
350 
351 	if (argc) {
352 		char *args[9], **argp = args;
353 
354 		if (argc > 2)
355 			usage();
356 		*argp++ = prompt;
357 		if (user) {
358 			*argp++ = strdup("-l");
359 			*argp++ = user;
360 		}
361 		if (src_addr) {
362 			*argp++ = strdup("-s");
363 			*argp++ = src_addr;
364 		}
365 		*argp++ = argv[0];		/* host */
366 		if (argc > 1)
367 			*argp++ = argv[1];	/* port */
368 		*argp = 0;
369 
370 		if (setjmp(toplevel) != 0)
371 			Exit(0);
372 		if (tn(argp - args, args) == 1)
373 			return (0);
374 		else
375 			return (1);
376 	}
377 	(void)setjmp(toplevel);
378 	for (;;) {
379 			command(1, 0, 0);
380 	}
381 	return 0;
382 }
383