xref: /freebsd/contrib/telnet/telnet/main.c (revision 39ee7a7a6bdd1557b1c3532abf60d139798ac88b)
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. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *	This product includes software developed by the University of
16  *	California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 
34 #if 0
35 #ifndef lint
36 static const char sccsid[] = "@(#)main.c	8.3 (Berkeley) 5/30/95";
37 #endif
38 #endif
39 #include <sys/cdefs.h>
40 __FBSDID("$FreeBSD$");
41 
42 #include <sys/param.h>
43 #include <sys/socket.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <unistd.h>
47 
48 #include "ring.h"
49 #include "externs.h"
50 #include "defines.h"
51 
52 #ifdef	AUTHENTICATION
53 #include <libtelnet/auth.h>
54 #endif
55 #ifdef	ENCRYPTION
56 #include <libtelnet/encrypt.h>
57 #endif
58 
59 /* These values need to be the same as defined in libtelnet/kerberos5.c */
60 /* Either define them in both places, or put in some common header file. */
61 #define OPTS_FORWARD_CREDS	0x00000002
62 #define OPTS_FORWARDABLE_CREDS	0x00000001
63 
64 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
65 char *ipsec_policy_in = NULL;
66 char *ipsec_policy_out = NULL;
67 #endif
68 
69 extern int tos;
70 
71 int family = AF_UNSPEC;
72 
73 /*
74  * Initialize variables.
75  */
76 void
77 tninit(void)
78 {
79     init_terminal();
80 
81     init_network();
82 
83     init_telnet();
84 
85     init_sys();
86 }
87 
88 static void
89 usage(void)
90 {
91 	fprintf(stderr, "usage: %s %s%s%s%s\n",
92 	    prompt,
93 #ifdef	AUTHENTICATION
94 	    "[-4] [-6] [-8] [-B baudrate] [-E] [-K] [-L] [-N] [-S tos] [-X atype]",
95 	    "\n\t[-c] [-d] [-e char] [-k realm] [-l user] [-f/-F] [-n tracefile] ",
96 #else
97 	    "[-4] [-6] [-8] [-B baudrate] [-E] [-L] [-N] [-S tos] [-c] [-d]",
98 	    "\n\t[-e char] [-l user] [-n tracefile] ",
99 #endif
100 	    "[-r] [-s src_addr] [-u] ",
101 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
102 	    "[-P policy] "
103 #endif
104 #ifdef	ENCRYPTION
105 	    "[-y] [host-name [port]]"
106 #else	/* ENCRYPTION */
107 	    "[host-name [port]]"
108 #endif	/* ENCRYPTION */
109 	);
110 	exit(1);
111 }
112 
113 /*
114  * main.  Parse arguments, invoke the protocol or command parser.
115  */
116 
117 int
118 main(int argc, char *argv[])
119 {
120 	u_long ultmp;
121 	int ch;
122 	char *ep, *user;
123 	char *src_addr = NULL;
124 #ifdef	FORWARD
125 	extern int forward_flags;
126 #endif	/* FORWARD */
127 
128 	tninit();		/* Clear out things */
129 
130 	TerminalSaveState();
131 
132 	if ((prompt = strrchr(argv[0], '/')))
133 		++prompt;
134 	else
135 		prompt = argv[0];
136 
137 	user = NULL;
138 
139 	rlogin = (strncmp(prompt, "rlog", 4) == 0) ? '~' : _POSIX_VDISABLE;
140 #ifdef AUTHENTICATION
141 	autologin = 1;
142 #else
143 	autologin = -1;
144 #endif
145 
146 #ifdef	ENCRYPTION
147 	encrypt_auto(1);
148 	decrypt_auto(1);
149 #endif
150 
151 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
152 #define IPSECOPT	"P:"
153 #else
154 #define IPSECOPT
155 #endif
156 	while ((ch = getopt(argc, argv,
157 			    "468B:EKLNS:X:acde:fFk:l:n:rs:uxy" IPSECOPT)) != -1)
158 #undef IPSECOPT
159 	{
160 		switch(ch) {
161 		case '4':
162 			family = AF_INET;
163 			break;
164 #ifdef INET6
165 		case '6':
166 			family = AF_INET6;
167 			break;
168 #endif
169 		case '8':
170 			eight = 3;	/* binary output and input */
171 			break;
172 		case 'B':
173 			DoBaudRate(optarg);
174 			break;
175 		case 'E':
176 			rlogin = escape = _POSIX_VDISABLE;
177 			break;
178 		case 'K':
179 #ifdef	AUTHENTICATION
180 			autologin = 0;
181 #endif
182 			break;
183 		case 'L':
184 			eight |= 2;	/* binary output only */
185 			break;
186 		case 'N':
187 			doaddrlookup = 0;
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