157416Smarkm/*
257416Smarkm * Copyright (c) 1988, 1990, 1993
357416Smarkm *	The Regents of the University of California.  All rights reserved.
457416Smarkm *
557416Smarkm * Redistribution and use in source and binary forms, with or without
657416Smarkm * modification, are permitted provided that the following conditions
757416Smarkm * are met:
857416Smarkm * 1. Redistributions of source code must retain the above copyright
957416Smarkm *    notice, this list of conditions and the following disclaimer.
1057416Smarkm * 2. Redistributions in binary form must reproduce the above copyright
1157416Smarkm *    notice, this list of conditions and the following disclaimer in the
1257416Smarkm *    documentation and/or other materials provided with the distribution.
1357416Smarkm * 3. All advertising materials mentioning features or use of this software
1457416Smarkm *    must display the following acknowledgement:
1557416Smarkm *	This product includes software developed by the University of
1657416Smarkm *	California, Berkeley and its contributors.
1757416Smarkm * 4. Neither the name of the University nor the names of its contributors
1857416Smarkm *    may be used to endorse or promote products derived from this software
1957416Smarkm *    without specific prior written permission.
2057416Smarkm *
2157416Smarkm * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2257416Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2357416Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2457416Smarkm * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2557416Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2657416Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2757416Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2857416Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2957416Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3057416Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3157416Smarkm * SUCH DAMAGE.
3257416Smarkm */
3357416Smarkm
3457416Smarkmstatic char *copyright[] = {
3557416Smarkm    "@(#) Copyright (c) 1988, 1990, 1993\n"
3657416Smarkm    "\tThe Regents of the University of California.  All rights reserved.\n",
3757416Smarkm    (char*)copyright
3857416Smarkm};
3957416Smarkm
4057416Smarkm#include "telnet_locl.h"
41233294SstasRCSID("$Id$");
4257416Smarkm
4357416Smarkm#if KRB5
4457416Smarkm#define FORWARD
4557416Smarkm#endif
4657416Smarkm
4757416Smarkm/*
4857416Smarkm * Initialize variables.
4957416Smarkm */
5057416Smarkmvoid
5157416Smarkmtninit(void)
5257416Smarkm{
5357416Smarkm    init_terminal();
5457416Smarkm
5557416Smarkm    init_network();
5657416Smarkm
5757416Smarkm    init_telnet();
5857416Smarkm
5957416Smarkm    init_sys();
6057416Smarkm}
6157416Smarkm
62178825Sdfrstatic void
63178825Sdfrusage(int exit_code)
6457416Smarkm{
6557416Smarkm  fprintf(stderr, "Usage: %s %s%s%s%s\n", prompt,
6657416Smarkm#ifdef	AUTHENTICATION
6757416Smarkm	  "[-8] [-E] [-K] [-L] [-G] [-S tos] [-X atype] [-a] [-c] [-d] [-e char]",
6857416Smarkm	  "\n\t[-k realm] [-l user] [-f/-F] [-n tracefile] ",
6957416Smarkm#else
7057416Smarkm	  "[-8] [-E] [-L] [-S tos] [-a] [-c] [-d] [-e char] [-l user]",
7157416Smarkm	  "\n\t[-n tracefile]",
7257416Smarkm#endif
7357416Smarkm	  "[-r] ",
7457416Smarkm#ifdef	ENCRYPTION
7557416Smarkm	  "[-x] [host-name [port]]"
7657416Smarkm#else
7757416Smarkm	  "[host-name [port]]"
7857416Smarkm#endif
7957416Smarkm    );
80178825Sdfr  exit(exit_code);
8157416Smarkm}
8257416Smarkm
8357416Smarkm/*
8457416Smarkm * main.  Parse arguments, invoke the protocol or command parser.
8557416Smarkm */
8657416Smarkm
8757416Smarkm
8857416Smarkm#ifdef	FORWARD
89102644Snectarint forward_option = 0; /* forward flags set from command line */
9057416Smarkm#endif	/* FORWARD */
91102644Snectarvoid
92102644Snectarset_forward_options(void)
93102644Snectar{
94102644Snectar#ifdef FORWARD
95102644Snectar	switch(forward_option) {
96102644Snectar	case 'f':
97102644Snectar		kerberos5_set_forward(1);
98102644Snectar		kerberos5_set_forwardable(0);
99102644Snectar		break;
100102644Snectar	case 'F':
101102644Snectar		kerberos5_set_forward(1);
102102644Snectar		kerberos5_set_forwardable(1);
103102644Snectar		break;
104102644Snectar	case 'G':
105102644Snectar		kerberos5_set_forward(0);
106102644Snectar		kerberos5_set_forwardable(0);
107102644Snectar		break;
108102644Snectar	default:
109102644Snectar		break;
110102644Snectar	}
111102644Snectar#endif
112102644Snectar}
11357416Smarkm
11457416Smarkm#ifdef KRB5
11557416Smarkm#define Authenticator asn1_Authenticator
11657416Smarkm#include <krb5.h>
11757416Smarkmstatic void
11857416Smarkmkrb5_init(void)
11957416Smarkm{
12057416Smarkm    krb5_context context;
12172445Sassar    krb5_error_code ret;
122178825Sdfr    krb5_boolean ret_val;
12357416Smarkm
12472445Sassar    ret = krb5_init_context(&context);
12572445Sassar    if (ret)
12672445Sassar	return;
12772445Sassar
128178825Sdfr#if defined(AUTHENTICATION) && defined(FORWARD)
129178825Sdfr    krb5_appdefault_boolean(context, NULL,
130178825Sdfr			    NULL, "forward",
131178825Sdfr			    0, &ret_val);
132178825Sdfr    if (ret_val)
133102644Snectar	    kerberos5_set_forward(1);
134178825Sdfr    krb5_appdefault_boolean(context, NULL,
135178825Sdfr			    NULL, "forwardable",
136178825Sdfr			    0, &ret_val);
137178825Sdfr    if (ret_val)
138102644Snectar	    kerberos5_set_forwardable(1);
13957416Smarkm#endif
14057416Smarkm#ifdef  ENCRYPTION
141233294Sstas    krb5_appdefault_boolean(context, NULL,
142178825Sdfr			    NULL, "encrypt",
143178825Sdfr			    0, &ret_val);
144178825Sdfr    if (ret_val) {
14557416Smarkm          encrypt_auto(1);
146233294Sstas          decrypt_auto(1);
14790926Snectar	  wantencryption = 1;
14857416Smarkm          EncryptVerbose(1);
14957416Smarkm        }
15057416Smarkm#endif
15157416Smarkm
15257416Smarkm    krb5_free_context(context);
15357416Smarkm}
15457416Smarkm#endif
15557416Smarkm
15657416Smarkmint
15757416Smarkmmain(int argc, char **argv)
15857416Smarkm{
15957416Smarkm	int ch;
16057416Smarkm	char *user;
16157416Smarkm
162127808Snectar	setprogname(argv[0]);
163127808Snectar
16457416Smarkm#ifdef KRB5
16557416Smarkm	krb5_init();
16657416Smarkm#endif
167233294Sstas
16857416Smarkm	tninit();		/* Clear out things */
16957416Smarkm
17057416Smarkm	TerminalSaveState();
17157416Smarkm
17257416Smarkm	if ((prompt = strrchr(argv[0], '/')))
17357416Smarkm		++prompt;
17457416Smarkm	else
17557416Smarkm		prompt = argv[0];
17657416Smarkm
17757416Smarkm	user = NULL;
17857416Smarkm
17957416Smarkm	rlogin = (strncmp(prompt, "rlog", 4) == 0) ? '~' : _POSIX_VDISABLE;
18057416Smarkm
181233294Sstas	/*
18257416Smarkm	 * if AUTHENTICATION and ENCRYPTION is set autologin will be
18357416Smarkm	 * se to true after the getopt switch; unless the -K option is
184233294Sstas	 * passed
18557416Smarkm	 */
18657416Smarkm	autologin = -1;
18757416Smarkm
188102644Snectar	if (argc == 2 && strcmp(argv[1], "--version") == 0) {
189102644Snectar	    print_version(NULL);
190102644Snectar	    exit(0);
191102644Snectar	}
192178825Sdfr	if (argc == 2 && strcmp(argv[1], "--help") == 0)
193178825Sdfr	    usage(0);
194102644Snectar
195178825Sdfr
19657416Smarkm	while((ch = getopt(argc, argv,
19757416Smarkm			   "78DEKLS:X:abcde:fFk:l:n:rxG")) != -1) {
19857416Smarkm		switch(ch) {
19957416Smarkm		case '8':
20057416Smarkm			eight = 3;	/* binary output and input */
20157416Smarkm			break;
20257416Smarkm		case '7':
20357416Smarkm			eight = 0;
20457416Smarkm			break;
20557416Smarkm		case 'b':
20657416Smarkm		    binary = 3;
20757416Smarkm		    break;
20857416Smarkm		case 'D': {
20957416Smarkm		    /* sometimes we don't want a mangled display */
21057416Smarkm		    char *p;
21157416Smarkm		    if((p = getenv("DISPLAY")))
21290926Snectar			env_define((unsigned char*)"DISPLAY", (unsigned char*)p);
21357416Smarkm		    break;
21457416Smarkm		}
21557416Smarkm		case 'E':
21657416Smarkm			rlogin = escape = _POSIX_VDISABLE;
21757416Smarkm			break;
21857416Smarkm		case 'K':
21957416Smarkm#ifdef	AUTHENTICATION
22057416Smarkm			autologin = 0;
22157416Smarkm#endif
22257416Smarkm			break;
22357416Smarkm		case 'L':
22457416Smarkm			eight |= 2;	/* binary output only */
22557416Smarkm			break;
22657416Smarkm		case 'S':
22757416Smarkm		    {
22857416Smarkm#ifdef	HAVE_PARSETOS
22957416Smarkm			extern int tos;
23057416Smarkm
23157416Smarkm			if ((tos = parsetos(optarg, "tcp")) < 0)
23257416Smarkm				fprintf(stderr, "%s%s%s%s\n",
23357416Smarkm					prompt, ": Bad TOS argument '",
23457416Smarkm					optarg,
23557416Smarkm					"; will try to use default TOS");
23657416Smarkm#else
23757416Smarkm			fprintf(stderr,
23857416Smarkm			   "%s: Warning: -S ignored, no parsetos() support.\n",
23957416Smarkm								prompt);
24057416Smarkm#endif
24157416Smarkm		    }
24257416Smarkm			break;
24357416Smarkm		case 'X':
24457416Smarkm#ifdef	AUTHENTICATION
24557416Smarkm			auth_disable_name(optarg);
24657416Smarkm#endif
24757416Smarkm			break;
24857416Smarkm		case 'a':
24957416Smarkm			autologin = 1;
25057416Smarkm			break;
25157416Smarkm		case 'c':
25257416Smarkm			skiprc = 1;
25357416Smarkm			break;
25457416Smarkm		case 'd':
25557416Smarkm			debug = 1;
25657416Smarkm			break;
25757416Smarkm		case 'e':
25857416Smarkm			set_escape_char(optarg);
25957416Smarkm			break;
26057416Smarkm		case 'f':
26157416Smarkm		case 'F':
262102644Snectar		case 'G':
26357416Smarkm#if defined(AUTHENTICATION) && defined(KRB5) && defined(FORWARD)
264102644Snectar			if (forward_option) {
26557416Smarkm			    fprintf(stderr,
266102644Snectar				    "%s: Only one of -f, -F and -G allowed.\n",
26757416Smarkm				    prompt);
268178825Sdfr			    usage(1);
26957416Smarkm			}
270102644Snectar			forward_option = ch;
27157416Smarkm#else
27257416Smarkm			fprintf(stderr,
273102644Snectar			 "%s: Warning: -%c ignored, no Kerberos V5 support.\n",
274102644Snectar				prompt, ch);
27557416Smarkm#endif
27657416Smarkm			break;
27757416Smarkm		case 'k':
278233294Sstas		    fprintf(stderr,
279233294Sstas			    "%s: Warning: -k ignored, no Kerberos V4 support.\n",
280233294Sstas			    prompt);
281233294Sstas		    break;
28257416Smarkm		case 'l':
28357416Smarkm		  if(autologin == 0){
28457416Smarkm		    fprintf(stderr, "%s: Warning: -K ignored\n", prompt);
28557416Smarkm		    autologin = -1;
28657416Smarkm		  }
28757416Smarkm			user = optarg;
28857416Smarkm			break;
28957416Smarkm		case 'n':
29057416Smarkm				SetNetTrace(optarg);
29157416Smarkm			break;
29257416Smarkm		case 'r':
29357416Smarkm			rlogin = '~';
29457416Smarkm			break;
29557416Smarkm		case 'x':
29657416Smarkm#ifdef	ENCRYPTION
29757416Smarkm			encrypt_auto(1);
29857416Smarkm			decrypt_auto(1);
29990926Snectar			wantencryption = 1;
30057416Smarkm			EncryptVerbose(1);
30157416Smarkm#else
30257416Smarkm			fprintf(stderr,
30357416Smarkm			    "%s: Warning: -x ignored, no ENCRYPT support.\n",
30457416Smarkm								prompt);
30557416Smarkm#endif
30657416Smarkm			break;
30757416Smarkm
30857416Smarkm		case '?':
30957416Smarkm		default:
310178825Sdfr			usage(1);
31157416Smarkm			/* NOTREACHED */
31257416Smarkm		}
31357416Smarkm	}
31457416Smarkm
31557416Smarkm	if (autologin == -1) {		/* esc@magic.fi; force  */
31657416Smarkm#if defined(AUTHENTICATION)
31757416Smarkm		autologin = 1;
31857416Smarkm#endif
31957416Smarkm#if defined(ENCRYPTION)
32057416Smarkm		encrypt_auto(1);
32157416Smarkm		decrypt_auto(1);
322102644Snectar		wantencryption = -1;
32357416Smarkm#endif
32457416Smarkm	}
32557416Smarkm
32657416Smarkm	if (autologin == -1)
32757416Smarkm		autologin = (rlogin == _POSIX_VDISABLE) ? 0 : 1;
32857416Smarkm
32957416Smarkm	argc -= optind;
33057416Smarkm	argv += optind;
33157416Smarkm
33257416Smarkm	if (argc) {
33357416Smarkm		char *args[7], **argp = args;
33457416Smarkm
33557416Smarkm		if (argc > 2)
336178825Sdfr			usage(1);
33757416Smarkm		*argp++ = prompt;
33857416Smarkm		if (user) {
33957416Smarkm			*argp++ = "-l";
34057416Smarkm			*argp++ = user;
34157416Smarkm		}
34257416Smarkm		*argp++ = argv[0];		/* host */
34357416Smarkm		if (argc > 1)
34457416Smarkm			*argp++ = argv[1];	/* port */
34557416Smarkm		*argp = 0;
34657416Smarkm
34757416Smarkm		if (setjmp(toplevel) != 0)
34857416Smarkm			Exit(0);
34957416Smarkm		if (tn(argp - args, args) == 1)
35057416Smarkm			return (0);
35157416Smarkm		else
35257416Smarkm			return (1);
35357416Smarkm	}
35457416Smarkm	setjmp(toplevel);
35557416Smarkm	for (;;) {
35657416Smarkm			command(1, 0, 0);
35757416Smarkm	}
35857416Smarkm}
359