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