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: src/contrib/telnet/telnet/main.c,v 1.20 2005/01/09 10:24:45 maxim Exp $");
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] [-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
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			    "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