129088Smarkm/*
229088Smarkm * Copyright (c) 1988, 1990, 1993
329088Smarkm *	The Regents of the University of California.  All rights reserved.
429088Smarkm *
529088Smarkm * Redistribution and use in source and binary forms, with or without
629088Smarkm * modification, are permitted provided that the following conditions
729088Smarkm * are met:
829088Smarkm * 1. Redistributions of source code must retain the above copyright
929088Smarkm *    notice, this list of conditions and the following disclaimer.
1029088Smarkm * 2. Redistributions in binary form must reproduce the above copyright
1129088Smarkm *    notice, this list of conditions and the following disclaimer in the
1229088Smarkm *    documentation and/or other materials provided with the distribution.
1329088Smarkm * 3. All advertising materials mentioning features or use of this software
1429088Smarkm *    must display the following acknowledgement:
1529088Smarkm *	This product includes software developed by the University of
1629088Smarkm *	California, Berkeley and its contributors.
1729088Smarkm * 4. Neither the name of the University nor the names of its contributors
1829088Smarkm *    may be used to endorse or promote products derived from this software
1929088Smarkm *    without specific prior written permission.
2029088Smarkm *
2129088Smarkm * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2229088Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2329088Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2429088Smarkm * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2529088Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2629088Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2729088Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2829088Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2929088Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3029088Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3129088Smarkm * SUCH DAMAGE.
3229088Smarkm */
3329088Smarkm
34114630Sobrien#if 0
3529088Smarkm#ifndef lint
3629181Smarkmstatic const char sccsid[] = "@(#)main.c	8.3 (Berkeley) 5/30/95";
3787139Smarkm#endif
38114630Sobrien#endif
39114630Sobrien#include <sys/cdefs.h>
40114630Sobrien__FBSDID("$FreeBSD$");
4129088Smarkm
42139937Smaxim#include <sys/param.h>
4356668Sshin#include <sys/socket.h>
4429181Smarkm#include <stdlib.h>
4581965Smarkm#include <string.h>
4681965Smarkm#include <unistd.h>
4729088Smarkm
4829088Smarkm#include "ring.h"
4929088Smarkm#include "externs.h"
5029088Smarkm#include "defines.h"
5129088Smarkm
5287139Smarkm#ifdef	AUTHENTICATION
5329181Smarkm#include <libtelnet/auth.h>
5429181Smarkm#endif
5587139Smarkm#ifdef	ENCRYPTION
5629181Smarkm#include <libtelnet/encrypt.h>
5729181Smarkm#endif
5829181Smarkm
5929088Smarkm/* These values need to be the same as defined in libtelnet/kerberos5.c */
6029088Smarkm/* Either define them in both places, or put in some common header file. */
6129088Smarkm#define OPTS_FORWARD_CREDS	0x00000002
6229088Smarkm#define OPTS_FORWARDABLE_CREDS	0x00000001
6329088Smarkm
6456668Sshin#if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
6556668Sshinchar *ipsec_policy_in = NULL;
6656668Sshinchar *ipsec_policy_out = NULL;
6756668Sshin#endif
6856668Sshin
69139937Smaximextern int tos;
70139937Smaxim
7156668Sshinint family = AF_UNSPEC;
7256668Sshin
7329088Smarkm/*
7429088Smarkm * Initialize variables.
7529088Smarkm */
7687139Smarkmvoid
7787139Smarkmtninit(void)
7829088Smarkm{
7929088Smarkm    init_terminal();
8029088Smarkm
8129088Smarkm    init_network();
8229088Smarkm
8329088Smarkm    init_telnet();
8429088Smarkm
8529088Smarkm    init_sys();
8629088Smarkm}
8729088Smarkm
8887139Smarkmstatic void
8987139Smarkmusage(void)
9029088Smarkm{
91103955Smarkm	fprintf(stderr, "usage: %s %s%s%s%s\n",
9229088Smarkm	    prompt,
9329088Smarkm#ifdef	AUTHENTICATION
9475263Snsayer	    "[-4] [-6] [-8] [-E] [-K] [-L] [-N] [-S tos] [-X atype] [-c] [-d]",
9547973Sru	    "\n\t[-e char] [-k realm] [-l user] [-f/-F] [-n tracefile] ",
9629088Smarkm#else
9779323Sru	    "[-4] [-6] [-8] [-E] [-L] [-N] [-S tos] [-c] [-d]",
9879323Sru	    "\n\t[-e char] [-l user] [-n tracefile] ",
9929088Smarkm#endif
10079323Sru	    "[-r] [-s src_addr] [-u] ",
10156668Sshin#if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
10279323Sru	    "[-P policy] "
10356668Sshin#endif
10429088Smarkm#ifdef	ENCRYPTION
10575263Snsayer	    "[-y] [host-name [port]]"
10629088Smarkm#else	/* ENCRYPTION */
10729088Smarkm	    "[host-name [port]]"
10829088Smarkm#endif	/* ENCRYPTION */
10929088Smarkm	);
11029088Smarkm	exit(1);
11129088Smarkm}
11229088Smarkm
11329088Smarkm/*
11429088Smarkm * main.  Parse arguments, invoke the protocol or command parser.
11529088Smarkm */
11629088Smarkm
11787139Smarkmint
11887139Smarkmmain(int argc, char *argv[])
11929088Smarkm{
120139937Smaxim	u_long ultmp;
12129088Smarkm	int ch;
122139937Smaxim	char *ep, *user;
12347973Sru	char *src_addr = NULL;
12429088Smarkm#ifdef	FORWARD
12529088Smarkm	extern int forward_flags;
12629088Smarkm#endif	/* FORWARD */
12729088Smarkm
12829088Smarkm	tninit();		/* Clear out things */
12929088Smarkm
13029088Smarkm	TerminalSaveState();
13129088Smarkm
13229181Smarkm	if ((prompt = strrchr(argv[0], '/')))
13329088Smarkm		++prompt;
13429088Smarkm	else
13529088Smarkm		prompt = argv[0];
13629088Smarkm
13729088Smarkm	user = NULL;
13829088Smarkm
13929088Smarkm	rlogin = (strncmp(prompt, "rlog", 4) == 0) ? '~' : _POSIX_VDISABLE;
14081965Smarkm#ifdef AUTHENTICATION
14175263Snsayer	autologin = 1;
14281965Smarkm#else
14381965Smarkm	autologin = -1;
14481965Smarkm#endif
14529088Smarkm
14687139Smarkm#ifdef	ENCRYPTION
14775263Snsayer	encrypt_auto(1);
14875263Snsayer	decrypt_auto(1);
14975263Snsayer#endif
15075263Snsayer
15156668Sshin#if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
15256668Sshin#define IPSECOPT	"P:"
15356668Sshin#else
15456668Sshin#define IPSECOPT
15556668Sshin#endif
15656668Sshin	while ((ch = getopt(argc, argv,
157139711Smaxim			    "468EKLNS:X:acde:fFk:l:n:rs:uxy" IPSECOPT)) != -1)
15856668Sshin#undef IPSECOPT
15956668Sshin	{
16029088Smarkm		switch(ch) {
16156668Sshin		case '4':
16256668Sshin			family = AF_INET;
16356668Sshin			break;
16456668Sshin#ifdef INET6
16556668Sshin		case '6':
16656668Sshin			family = AF_INET6;
16756668Sshin			break;
16856668Sshin#endif
16929088Smarkm		case '8':
17029088Smarkm			eight = 3;	/* binary output and input */
17129088Smarkm			break;
17229088Smarkm		case 'E':
17329088Smarkm			rlogin = escape = _POSIX_VDISABLE;
17429088Smarkm			break;
17529088Smarkm		case 'K':
17629088Smarkm#ifdef	AUTHENTICATION
17729088Smarkm			autologin = 0;
17829088Smarkm#endif
17929088Smarkm			break;
18029088Smarkm		case 'L':
18129088Smarkm			eight |= 2;	/* binary output only */
18229088Smarkm			break;
18347973Sru		case 'N':
18447973Sru			doaddrlookup = 0;
18547973Sru			break;
18629088Smarkm		case 'S':
18729088Smarkm#ifdef	HAS_GETTOS
18829088Smarkm
18929088Smarkm			if ((tos = parsetos(optarg, "tcp")) < 0)
19029088Smarkm				fprintf(stderr, "%s%s%s%s\n",
19129088Smarkm					prompt, ": Bad TOS argument '",
19229088Smarkm					optarg,
19329088Smarkm					"; will try to use default TOS");
19429088Smarkm#else
195139937Smaxim#define	MAXTOS	255
196139937Smaxim			ultmp = strtoul(optarg, &ep, 0);
197139937Smaxim			if (*ep || ep == optarg || ultmp > MAXTOS)
198139937Smaxim				fprintf(stderr, "%s%s%s%s\n",
199139937Smaxim					prompt, ": Bad TOS argument '",
200139937Smaxim					optarg,
201139937Smaxim					"; will try to use default TOS");
202139937Smaxim			else
203139937Smaxim				tos = ultmp;
20429088Smarkm#endif
20529088Smarkm			break;
20629088Smarkm		case 'X':
20729088Smarkm#ifdef	AUTHENTICATION
20829088Smarkm			auth_disable_name(optarg);
20929088Smarkm#endif
21029088Smarkm			break;
21129088Smarkm		case 'a':
21281965Smarkm#ifdef	AUTHENTICATION
21375263Snsayer			/* It's the default now, so ignore */
21481965Smarkm#else
21581965Smarkm			autologin = 1;
21681965Smarkm#endif
21729088Smarkm			break;
21829088Smarkm		case 'c':
21929088Smarkm			skiprc = 1;
22029088Smarkm			break;
22129088Smarkm		case 'd':
222114911Smarkm			telnet_debug = 1;
22329088Smarkm			break;
22429088Smarkm		case 'e':
22529088Smarkm			set_escape_char(optarg);
22629088Smarkm			break;
22729088Smarkm		case 'f':
22887139Smarkm#ifdef	AUTHENTICATION
22987139Smarkm#if defined(KRB5) && defined(FORWARD)
23029088Smarkm			if (forward_flags & OPTS_FORWARD_CREDS) {
23129088Smarkm			    fprintf(stderr,
23229088Smarkm				    "%s: Only one of -f and -F allowed.\n",
23329088Smarkm				    prompt);
23429088Smarkm			    usage();
23529088Smarkm			}
23629088Smarkm			forward_flags |= OPTS_FORWARD_CREDS;
23729088Smarkm#else
23829088Smarkm			fprintf(stderr,
23929088Smarkm			 "%s: Warning: -f ignored, no Kerberos V5 support.\n",
24029088Smarkm				prompt);
24129088Smarkm#endif
24287139Smarkm#else
24387139Smarkm			fprintf(stderr,
24487139Smarkm			 "%s: Warning: -f ignored, no Kerberos V5 support.\n",
24587139Smarkm				prompt);
24687139Smarkm#endif
24729088Smarkm			break;
24829088Smarkm		case 'F':
24987139Smarkm#ifdef	AUTHENTICATION
25087139Smarkm#if defined(KRB5) && defined(FORWARD)
25129088Smarkm			if (forward_flags & OPTS_FORWARD_CREDS) {
25229088Smarkm			    fprintf(stderr,
25329088Smarkm				    "%s: Only one of -f and -F allowed.\n",
25429088Smarkm				    prompt);
25529088Smarkm			    usage();
25629088Smarkm			}
25729088Smarkm			forward_flags |= OPTS_FORWARD_CREDS;
25829088Smarkm			forward_flags |= OPTS_FORWARDABLE_CREDS;
25929088Smarkm#else
26029088Smarkm			fprintf(stderr,
26129088Smarkm			 "%s: Warning: -F ignored, no Kerberos V5 support.\n",
26229088Smarkm				prompt);
26329088Smarkm#endif
26487139Smarkm#else
26587139Smarkm			fprintf(stderr,
26687139Smarkm			 "%s: Warning: -F ignored, no Kerberos V5 support.\n",
26787139Smarkm				prompt);
26887139Smarkm#endif
26929088Smarkm			break;
27029088Smarkm		case 'k':
27187139Smarkm#ifdef	AUTHENTICATION
27287139Smarkm#if defined(KRB4)
27329088Smarkm		    {
27429088Smarkm			extern char *dest_realm, dst_realm_buf[], dst_realm_sz;
27529088Smarkm			dest_realm = dst_realm_buf;
27629088Smarkm			(void)strncpy(dest_realm, optarg, dst_realm_sz);
27729088Smarkm		    }
27829088Smarkm#else
27929088Smarkm			fprintf(stderr,
28029088Smarkm			   "%s: Warning: -k ignored, no Kerberos V4 support.\n",
28129088Smarkm								prompt);
28229088Smarkm#endif
28387139Smarkm#else
28487139Smarkm			fprintf(stderr,
28587139Smarkm			   "%s: Warning: -k ignored, no Kerberos V4 support.\n",
28687139Smarkm								prompt);
28787139Smarkm#endif
28829088Smarkm			break;
28929088Smarkm		case 'l':
29081965Smarkm#ifdef	AUTHENTICATION
29181965Smarkm			/* This is the default now, so ignore it */
29281965Smarkm#else
29381965Smarkm			autologin = 1;
29481965Smarkm#endif
29529088Smarkm			user = optarg;
29629088Smarkm			break;
29729088Smarkm		case 'n':
29829088Smarkm				SetNetTrace(optarg);
29929088Smarkm			break;
30029088Smarkm		case 'r':
30129088Smarkm			rlogin = '~';
30229088Smarkm			break;
30347973Sru		case 's':
30447973Sru			src_addr = optarg;
30547973Sru			break;
30679323Sru		case 'u':
30779323Sru			family = AF_UNIX;
30879323Sru			break;
30929088Smarkm		case 'x':
31087139Smarkm#ifndef	ENCRYPTION
31181965Smarkm			fprintf(stderr,
31281965Smarkm			    "%s: Warning: -x ignored, no ENCRYPT support.\n",
31381965Smarkm								prompt);
31481965Smarkm#endif	/* ENCRYPTION */
31575263Snsayer			break;
31675263Snsayer		case 'y':
31729088Smarkm#ifdef	ENCRYPTION
31875263Snsayer			encrypt_auto(0);
31975263Snsayer			decrypt_auto(0);
32081965Smarkm#else
32181965Smarkm			fprintf(stderr,
32281965Smarkm			    "%s: Warning: -y ignored, no ENCRYPT support.\n",
32381965Smarkm								prompt);
32429088Smarkm#endif	/* ENCRYPTION */
32529088Smarkm			break;
32656668Sshin#if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
32756668Sshin		case 'P':
32856668Sshin			if (!strncmp("in", optarg, 2))
32956668Sshin				ipsec_policy_in = strdup(optarg);
33056668Sshin			else if (!strncmp("out", optarg, 3))
33156668Sshin				ipsec_policy_out = strdup(optarg);
33256668Sshin			else
33356668Sshin				usage();
33456668Sshin			break;
33556668Sshin#endif
33629088Smarkm		case '?':
33729088Smarkm		default:
33829088Smarkm			usage();
33929088Smarkm			/* NOTREACHED */
34029088Smarkm		}
34129088Smarkm	}
34281965Smarkm	if (autologin == -1)
34381965Smarkm		autologin = (rlogin == _POSIX_VDISABLE) ? 0 : 1;
34474138Sassar
34529088Smarkm	argc -= optind;
34629088Smarkm	argv += optind;
34729088Smarkm
34829088Smarkm	if (argc) {
34947973Sru		char *args[9], **argp = args;
35029088Smarkm
35129088Smarkm		if (argc > 2)
35229088Smarkm			usage();
35329088Smarkm		*argp++ = prompt;
35429088Smarkm		if (user) {
35587139Smarkm			*argp++ = strdup("-l");
35629088Smarkm			*argp++ = user;
35729088Smarkm		}
35847973Sru		if (src_addr) {
35987139Smarkm			*argp++ = strdup("-s");
36047973Sru			*argp++ = src_addr;
36147973Sru		}
36229088Smarkm		*argp++ = argv[0];		/* host */
36329088Smarkm		if (argc > 1)
36429088Smarkm			*argp++ = argv[1];	/* port */
36529088Smarkm		*argp = 0;
36629088Smarkm
36729088Smarkm		if (setjmp(toplevel) != 0)
36829088Smarkm			Exit(0);
36929088Smarkm		if (tn(argp - args, args) == 1)
37029088Smarkm			return (0);
37129088Smarkm		else
37229088Smarkm			return (1);
37329088Smarkm	}
37429088Smarkm	(void)setjmp(toplevel);
37529088Smarkm	for (;;) {
37629088Smarkm			command(1, 0, 0);
37729088Smarkm	}
37829181Smarkm	return 0;
37929088Smarkm}
380