main.c revision 275508
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
36static const char sccsid[] = "@(#)main.c	8.3 (Berkeley) 5/30/95";
37#endif
38#endif
39#include <sys/cdefs.h>
40__FBSDID("$FreeBSD: stable/10/contrib/telnet/telnet/main.c 275508 2014-12-05 12:23:29Z ngie $");
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)
65char *ipsec_policy_in = NULL;
66char *ipsec_policy_out = NULL;
67#endif
68
69extern int tos;
70
71int family = AF_UNSPEC;
72
73/*
74 * Initialize variables.
75 */
76void
77tninit(void)
78{
79    init_terminal();
80
81    init_network();
82
83    init_telnet();
84
85    init_sys();
86}
87
88static void
89usage(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
117int
118main(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