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