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