xref: /freebsd/contrib/telnet/telnet/main.c (revision 38f0b757fd84d17d0fc24739a7cda160c4516d81)
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] [-E] [-K] [-L] [-N] [-S tos] [-X atype] [-c] [-d]",
95 	    "\n\t[-e char] [-k realm] [-l user] [-f/-F] [-n tracefile] ",
96 #else
97 	    "[-4] [-6] [-8] [-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 			    "468EKLNS: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 '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 'S':
187 #ifdef	HAS_GETTOS
188 
189 			if ((tos = parsetos(optarg, "tcp")) < 0)
190 				fprintf(stderr, "%s%s%s%s\n",
191 					prompt, ": Bad TOS argument '",
192 					optarg,
193 					"; will try to use default TOS");
194 #else
195 #define	MAXTOS	255
196 			ultmp = strtoul(optarg, &ep, 0);
197 			if (*ep || ep == optarg || ultmp > MAXTOS)
198 				fprintf(stderr, "%s%s%s%s\n",
199 					prompt, ": Bad TOS argument '",
200 					optarg,
201 					"; will try to use default TOS");
202 			else
203 				tos = ultmp;
204 #endif
205 			break;
206 		case 'X':
207 #ifdef	AUTHENTICATION
208 			auth_disable_name(optarg);
209 #endif
210 			break;
211 		case 'a':
212 #ifdef	AUTHENTICATION
213 			/* It's the default now, so ignore */
214 #else
215 			autologin = 1;
216 #endif
217 			break;
218 		case 'c':
219 			skiprc = 1;
220 			break;
221 		case 'd':
222 			telnet_debug = 1;
223 			break;
224 		case 'e':
225 			set_escape_char(optarg);
226 			break;
227 		case 'f':
228 #ifdef	AUTHENTICATION
229 #if defined(KRB5) && defined(FORWARD)
230 			if (forward_flags & OPTS_FORWARD_CREDS) {
231 			    fprintf(stderr,
232 				    "%s: Only one of -f and -F allowed.\n",
233 				    prompt);
234 			    usage();
235 			}
236 			forward_flags |= OPTS_FORWARD_CREDS;
237 #else
238 			fprintf(stderr,
239 			 "%s: Warning: -f ignored, no Kerberos V5 support.\n",
240 				prompt);
241 #endif
242 #else
243 			fprintf(stderr,
244 			 "%s: Warning: -f ignored, no Kerberos V5 support.\n",
245 				prompt);
246 #endif
247 			break;
248 		case 'F':
249 #ifdef	AUTHENTICATION
250 #if defined(KRB5) && defined(FORWARD)
251 			if (forward_flags & OPTS_FORWARD_CREDS) {
252 			    fprintf(stderr,
253 				    "%s: Only one of -f and -F allowed.\n",
254 				    prompt);
255 			    usage();
256 			}
257 			forward_flags |= OPTS_FORWARD_CREDS;
258 			forward_flags |= OPTS_FORWARDABLE_CREDS;
259 #else
260 			fprintf(stderr,
261 			 "%s: Warning: -F ignored, no Kerberos V5 support.\n",
262 				prompt);
263 #endif
264 #else
265 			fprintf(stderr,
266 			 "%s: Warning: -F ignored, no Kerberos V5 support.\n",
267 				prompt);
268 #endif
269 			break;
270 		case 'k':
271 #ifdef	AUTHENTICATION
272 #if defined(KRB4)
273 		    {
274 			extern char *dest_realm, dst_realm_buf[], dst_realm_sz;
275 			dest_realm = dst_realm_buf;
276 			(void)strncpy(dest_realm, optarg, dst_realm_sz);
277 		    }
278 #else
279 			fprintf(stderr,
280 			   "%s: Warning: -k ignored, no Kerberos V4 support.\n",
281 								prompt);
282 #endif
283 #else
284 			fprintf(stderr,
285 			   "%s: Warning: -k ignored, no Kerberos V4 support.\n",
286 								prompt);
287 #endif
288 			break;
289 		case 'l':
290 #ifdef	AUTHENTICATION
291 			/* This is the default now, so ignore it */
292 #else
293 			autologin = 1;
294 #endif
295 			user = optarg;
296 			break;
297 		case 'n':
298 				SetNetTrace(optarg);
299 			break;
300 		case 'r':
301 			rlogin = '~';
302 			break;
303 		case 's':
304 			src_addr = optarg;
305 			break;
306 		case 'u':
307 			family = AF_UNIX;
308 			break;
309 		case 'x':
310 #ifndef	ENCRYPTION
311 			fprintf(stderr,
312 			    "%s: Warning: -x ignored, no ENCRYPT support.\n",
313 								prompt);
314 #endif	/* ENCRYPTION */
315 			break;
316 		case 'y':
317 #ifdef	ENCRYPTION
318 			encrypt_auto(0);
319 			decrypt_auto(0);
320 #else
321 			fprintf(stderr,
322 			    "%s: Warning: -y ignored, no ENCRYPT support.\n",
323 								prompt);
324 #endif	/* ENCRYPTION */
325 			break;
326 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
327 		case 'P':
328 			if (!strncmp("in", optarg, 2))
329 				ipsec_policy_in = strdup(optarg);
330 			else if (!strncmp("out", optarg, 3))
331 				ipsec_policy_out = strdup(optarg);
332 			else
333 				usage();
334 			break;
335 #endif
336 		case '?':
337 		default:
338 			usage();
339 			/* NOTREACHED */
340 		}
341 	}
342 	if (autologin == -1)
343 		autologin = (rlogin == _POSIX_VDISABLE) ? 0 : 1;
344 
345 	argc -= optind;
346 	argv += optind;
347 
348 	if (argc) {
349 		char *args[9], **argp = args;
350 
351 		if (argc > 2)
352 			usage();
353 		*argp++ = prompt;
354 		if (user) {
355 			*argp++ = strdup("-l");
356 			*argp++ = user;
357 		}
358 		if (src_addr) {
359 			*argp++ = strdup("-s");
360 			*argp++ = src_addr;
361 		}
362 		*argp++ = argv[0];		/* host */
363 		if (argc > 1)
364 			*argp++ = argv[1];	/* port */
365 		*argp = 0;
366 
367 		if (setjmp(toplevel) != 0)
368 			Exit(0);
369 		if (tn(argp - args, args) == 1)
370 			return (0);
371 		else
372 			return (1);
373 	}
374 	(void)setjmp(toplevel);
375 	for (;;) {
376 			command(1, 0, 0);
377 	}
378 	return 0;
379 }
380