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