xref: /freebsd/contrib/telnet/telnet/main.c (revision 094517119c62c23369d545a7475ae982d86330a3)
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 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD$");
37 
38 #include <sys/param.h>
39 #include <sys/socket.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <unistd.h>
43 
44 #include "ring.h"
45 #include "externs.h"
46 #include "defines.h"
47 
48 #ifdef	AUTHENTICATION
49 #include <libtelnet/auth.h>
50 #endif
51 #ifdef	ENCRYPTION
52 #include <libtelnet/encrypt.h>
53 #endif
54 
55 /* These values need to be the same as defined in libtelnet/kerberos5.c */
56 /* Either define them in both places, or put in some common header file. */
57 #define OPTS_FORWARD_CREDS	0x00000002
58 #define OPTS_FORWARDABLE_CREDS	0x00000001
59 
60 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
61 char *ipsec_policy_in = NULL;
62 char *ipsec_policy_out = NULL;
63 #endif
64 
65 extern int tos;
66 extern int quiet_mode;
67 
68 int family = AF_UNSPEC;
69 
70 /*
71  * Initialize variables.
72  */
73 void
74 tninit(void)
75 {
76     init_terminal();
77 
78     init_network();
79 
80     init_telnet();
81 
82     init_sys();
83 }
84 
85 static void
86 usage(void)
87 {
88 	fprintf(stderr, "usage: %s %s%s%s%s\n",
89 	    prompt,
90 #ifdef	AUTHENTICATION
91 	    "[-4] [-6] [-8] [-B baudrate] [-E] [-K] [-L] [-N] [-S tos] [-X atype]",
92 	    "\n\t[-c] [-d] [-e char] [-k realm] [-l user] [-f/-F] [-n tracefile] ",
93 #else
94 	    "[-4] [-6] [-8] [-B baudrate] [-E] [-L] [-N] [-S tos] [-c] [-d]",
95 	    "\n\t[-e char] [-l user] [-n tracefile] ",
96 #endif
97 	    "[-r] [-s src_addr] [-u] ",
98 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
99 	    "[-P policy] "
100 #endif
101 #ifdef	ENCRYPTION
102 	    "[-y] [host-name [port]]"
103 #else	/* ENCRYPTION */
104 	    "[host-name [port]]"
105 #endif	/* ENCRYPTION */
106 	);
107 	exit(1);
108 }
109 
110 /*
111  * main.  Parse arguments, invoke the protocol or command parser.
112  */
113 
114 int
115 main(int argc, char *argv[])
116 {
117 	u_long ultmp;
118 	int ch;
119 	char *ep, *user;
120 	char *src_addr = NULL;
121 #ifdef	FORWARD
122 	extern int forward_flags;
123 #endif	/* FORWARD */
124 
125 	setbuf(stdout, NULL);
126 	setbuf(stderr, NULL);
127 	tninit();		/* Clear out things */
128 
129 	TerminalSaveState();
130 
131 	if ((prompt = strrchr(argv[0], '/')))
132 		++prompt;
133 	else
134 		prompt = argv[0];
135 
136 	user = NULL;
137 
138 	rlogin = (strncmp(prompt, "rlog", 4) == 0) ? '~' : _POSIX_VDISABLE;
139 #ifdef AUTHENTICATION
140 	autologin = 1;
141 #else
142 	autologin = -1;
143 #endif
144 
145 #ifdef	ENCRYPTION
146 	encrypt_auto(1);
147 	decrypt_auto(1);
148 #endif
149 
150 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
151 #define IPSECOPT	"P:"
152 #else
153 #define IPSECOPT
154 #endif
155 	while ((ch = getopt(argc, argv,
156 			    "468B:EKLNQS:X:acde:fFk:l:n:rs:uxy" IPSECOPT)) != -1)
157 #undef IPSECOPT
158 	{
159 		switch(ch) {
160 		case '4':
161 			family = AF_INET;
162 			break;
163 #ifdef INET6
164 		case '6':
165 			family = AF_INET6;
166 			break;
167 #endif
168 		case '8':
169 			eight = 3;	/* binary output and input */
170 			break;
171 		case 'B':
172 			DoBaudRate(optarg);
173 			break;
174 		case 'E':
175 			rlogin = escape = _POSIX_VDISABLE;
176 			break;
177 		case 'K':
178 #ifdef	AUTHENTICATION
179 			autologin = 0;
180 #endif
181 			break;
182 		case 'L':
183 			eight |= 2;	/* binary output only */
184 			break;
185 		case 'N':
186 			doaddrlookup = 0;
187 			break;
188 		case 'Q':
189 			quiet_mode = 1;
190 			break;
191 		case 'S':
192 #ifdef	HAS_GETTOS
193 
194 			if ((tos = parsetos(optarg, "tcp")) < 0)
195 				fprintf(stderr, "%s%s%s%s\n",
196 					prompt, ": Bad TOS argument '",
197 					optarg,
198 					"; will try to use default TOS");
199 #else
200 #define	MAXTOS	255
201 			ultmp = strtoul(optarg, &ep, 0);
202 			if (*ep || ep == optarg || ultmp > MAXTOS)
203 				fprintf(stderr, "%s%s%s%s\n",
204 					prompt, ": Bad TOS argument '",
205 					optarg,
206 					"; will try to use default TOS");
207 			else
208 				tos = ultmp;
209 #endif
210 			break;
211 		case 'X':
212 #ifdef	AUTHENTICATION
213 			auth_disable_name(optarg);
214 #endif
215 			break;
216 		case 'a':
217 #ifdef	AUTHENTICATION
218 			/* It's the default now, so ignore */
219 #else
220 			autologin = 1;
221 #endif
222 			break;
223 		case 'c':
224 			skiprc = 1;
225 			break;
226 		case 'd':
227 			telnet_debug = 1;
228 			break;
229 		case 'e':
230 			set_escape_char(optarg);
231 			break;
232 		case 'f':
233 #ifdef	AUTHENTICATION
234 #if defined(KRB5) && defined(FORWARD)
235 			if (forward_flags & OPTS_FORWARD_CREDS) {
236 			    fprintf(stderr,
237 				    "%s: Only one of -f and -F allowed.\n",
238 				    prompt);
239 			    usage();
240 			}
241 			forward_flags |= OPTS_FORWARD_CREDS;
242 #else
243 			fprintf(stderr,
244 			 "%s: Warning: -f ignored, no Kerberos V5 support.\n",
245 				prompt);
246 #endif
247 #else
248 			fprintf(stderr,
249 			 "%s: Warning: -f ignored, no Kerberos V5 support.\n",
250 				prompt);
251 #endif
252 			break;
253 		case 'F':
254 #ifdef	AUTHENTICATION
255 #if defined(KRB5) && defined(FORWARD)
256 			if (forward_flags & OPTS_FORWARD_CREDS) {
257 			    fprintf(stderr,
258 				    "%s: Only one of -f and -F allowed.\n",
259 				    prompt);
260 			    usage();
261 			}
262 			forward_flags |= OPTS_FORWARD_CREDS;
263 			forward_flags |= OPTS_FORWARDABLE_CREDS;
264 #else
265 			fprintf(stderr,
266 			 "%s: Warning: -F ignored, no Kerberos V5 support.\n",
267 				prompt);
268 #endif
269 #else
270 			fprintf(stderr,
271 			 "%s: Warning: -F ignored, no Kerberos V5 support.\n",
272 				prompt);
273 #endif
274 			break;
275 		case 'k':
276 #ifdef	AUTHENTICATION
277 #if defined(KRB4)
278 		    {
279 			extern char *dest_realm, dst_realm_buf[], dst_realm_sz;
280 			dest_realm = dst_realm_buf;
281 			(void)strncpy(dest_realm, optarg, dst_realm_sz);
282 		    }
283 #else
284 			fprintf(stderr,
285 			   "%s: Warning: -k ignored, no Kerberos V4 support.\n",
286 								prompt);
287 #endif
288 #else
289 			fprintf(stderr,
290 			   "%s: Warning: -k ignored, no Kerberos V4 support.\n",
291 								prompt);
292 #endif
293 			break;
294 		case 'l':
295 #ifdef	AUTHENTICATION
296 			/* This is the default now, so ignore it */
297 #else
298 			autologin = 1;
299 #endif
300 			user = optarg;
301 			break;
302 		case 'n':
303 				SetNetTrace(optarg);
304 			break;
305 		case 'r':
306 			rlogin = '~';
307 			break;
308 		case 's':
309 			src_addr = optarg;
310 			break;
311 		case 'u':
312 			family = AF_UNIX;
313 			break;
314 		case 'x':
315 #ifndef	ENCRYPTION
316 			fprintf(stderr,
317 			    "%s: Warning: -x ignored, no ENCRYPT support.\n",
318 								prompt);
319 #endif	/* ENCRYPTION */
320 			break;
321 		case 'y':
322 #ifdef	ENCRYPTION
323 			encrypt_auto(0);
324 			decrypt_auto(0);
325 #else
326 			fprintf(stderr,
327 			    "%s: Warning: -y ignored, no ENCRYPT support.\n",
328 								prompt);
329 #endif	/* ENCRYPTION */
330 			break;
331 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
332 		case 'P':
333 			if (!strncmp("in", optarg, 2))
334 				ipsec_policy_in = strdup(optarg);
335 			else if (!strncmp("out", optarg, 3))
336 				ipsec_policy_out = strdup(optarg);
337 			else
338 				usage();
339 			break;
340 #endif
341 		case '?':
342 		default:
343 			usage();
344 			/* NOTREACHED */
345 		}
346 	}
347 	if (autologin == -1)
348 		autologin = (rlogin == _POSIX_VDISABLE) ? 0 : 1;
349 
350 	argc -= optind;
351 	argv += optind;
352 
353 	if (argc) {
354 		char *args[9], **argp = args;
355 
356 		if (argc > 2)
357 			usage();
358 		*argp++ = prompt;
359 		if (user) {
360 			*argp++ = strdup("-l");
361 			*argp++ = user;
362 		}
363 		if (src_addr) {
364 			*argp++ = strdup("-s");
365 			*argp++ = src_addr;
366 		}
367 		*argp++ = argv[0];		/* host */
368 		if (argc > 1)
369 			*argp++ = argv[1];	/* port */
370 		*argp = 0;
371 
372 		if (setjmp(toplevel) != 0)
373 			Exit(0);
374 		if (tn(argp - args, args) == 1)
375 			return (0);
376 		else
377 			return (1);
378 	}
379 	(void)setjmp(toplevel);
380 	for (;;) {
381 			command(1, 0, 0);
382 	}
383 	return 0;
384 }
385