main.c revision 90926
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"
4190926SnectarRCSID("$Id: main.c,v 1.34 2001/12/20 20:39:52 joda Exp $");
4257416Smarkm
4357416Smarkm/* These values need to be the same as defined in libtelnet/kerberos5.c */
4457416Smarkm/* Either define them in both places, or put in some common header file. */
4557416Smarkm#define OPTS_FORWARD_CREDS	0x00000002
4657416Smarkm#define OPTS_FORWARDABLE_CREDS	0x00000001
4757416Smarkm
4857416Smarkm#if KRB5
4957416Smarkm#define FORWARD
5057416Smarkm#endif
5157416Smarkm
5257416Smarkm/*
5357416Smarkm * Initialize variables.
5457416Smarkm */
5557416Smarkmvoid
5657416Smarkmtninit(void)
5757416Smarkm{
5857416Smarkm    init_terminal();
5957416Smarkm
6057416Smarkm    init_network();
6157416Smarkm
6257416Smarkm    init_telnet();
6357416Smarkm
6457416Smarkm    init_sys();
6557416Smarkm}
6657416Smarkm
6757416Smarkmvoid
6857416Smarkmusage(void)
6957416Smarkm{
7057416Smarkm  fprintf(stderr, "Usage: %s %s%s%s%s\n", prompt,
7157416Smarkm#ifdef	AUTHENTICATION
7257416Smarkm	  "[-8] [-E] [-K] [-L] [-G] [-S tos] [-X atype] [-a] [-c] [-d] [-e char]",
7357416Smarkm	  "\n\t[-k realm] [-l user] [-f/-F] [-n tracefile] ",
7457416Smarkm#else
7557416Smarkm	  "[-8] [-E] [-L] [-S tos] [-a] [-c] [-d] [-e char] [-l user]",
7657416Smarkm	  "\n\t[-n tracefile]",
7757416Smarkm#endif
7857416Smarkm	  "[-r] ",
7957416Smarkm#ifdef	ENCRYPTION
8057416Smarkm	  "[-x] [host-name [port]]"
8157416Smarkm#else
8257416Smarkm	  "[host-name [port]]"
8357416Smarkm#endif
8457416Smarkm    );
8557416Smarkm  exit(1);
8657416Smarkm}
8757416Smarkm
8857416Smarkm/*
8957416Smarkm * main.  Parse arguments, invoke the protocol or command parser.
9057416Smarkm */
9157416Smarkm
9257416Smarkm
9357416Smarkm#ifdef	FORWARD
9457416Smarkmextern int forward_flags;
9557416Smarkmstatic int default_forward=0;
9657416Smarkm#endif	/* FORWARD */
9757416Smarkm
9857416Smarkm#ifdef KRB5
9957416Smarkm/* XXX ugly hack to setup dns-proxy stuff */
10057416Smarkm#define Authenticator asn1_Authenticator
10157416Smarkm#include <krb5.h>
10257416Smarkmstatic void
10357416Smarkmkrb5_init(void)
10457416Smarkm{
10557416Smarkm    krb5_context context;
10672445Sassar    krb5_error_code ret;
10757416Smarkm
10872445Sassar    ret = krb5_init_context(&context);
10972445Sassar    if (ret)
11072445Sassar	return;
11172445Sassar
11257416Smarkm#if defined(AUTHENTICATION) && defined(KRB5) && defined(FORWARD)
11357416Smarkm    if (krb5_config_get_bool (context, NULL,
11457416Smarkm         "libdefaults", "forward", NULL)) {
11557416Smarkm           forward_flags |= OPTS_FORWARD_CREDS;
11657416Smarkm           default_forward=1;
11757416Smarkm    }
11857416Smarkm    if (krb5_config_get_bool (context, NULL,
11957416Smarkm         "libdefaults", "forwardable", NULL)) {
12057416Smarkm           forward_flags |= OPTS_FORWARDABLE_CREDS;
12157416Smarkm           default_forward=1;
12257416Smarkm    }
12357416Smarkm#endif
12457416Smarkm#ifdef  ENCRYPTION
12557416Smarkm    if (krb5_config_get_bool (context, NULL,
12657416Smarkm        "libdefaults", "encrypt", NULL)) {
12757416Smarkm          encrypt_auto(1);
12857416Smarkm          decrypt_auto(1);
12990926Snectar	  wantencryption = 1;
13057416Smarkm          EncryptVerbose(1);
13157416Smarkm        }
13257416Smarkm#endif
13357416Smarkm
13457416Smarkm    krb5_free_context(context);
13557416Smarkm}
13657416Smarkm#endif
13757416Smarkm
13890926Snectar#if defined(AUTHENTICATION) && defined(KRB4)
13990926Snectarextern char *dest_realm, dst_realm_buf[];
14090926Snectarextern int dst_realm_sz;
14190926Snectar#endif
14290926Snectar
14357416Smarkmint
14457416Smarkmmain(int argc, char **argv)
14557416Smarkm{
14657416Smarkm	int ch;
14757416Smarkm	char *user;
14857416Smarkm
14957416Smarkm#ifdef KRB5
15057416Smarkm	krb5_init();
15157416Smarkm#endif
15257416Smarkm
15357416Smarkm	tninit();		/* Clear out things */
15457416Smarkm
15557416Smarkm	TerminalSaveState();
15657416Smarkm
15757416Smarkm	if ((prompt = strrchr(argv[0], '/')))
15857416Smarkm		++prompt;
15957416Smarkm	else
16057416Smarkm		prompt = argv[0];
16157416Smarkm
16257416Smarkm	user = NULL;
16357416Smarkm
16457416Smarkm	rlogin = (strncmp(prompt, "rlog", 4) == 0) ? '~' : _POSIX_VDISABLE;
16557416Smarkm
16657416Smarkm	/*
16757416Smarkm	 * if AUTHENTICATION and ENCRYPTION is set autologin will be
16857416Smarkm	 * se to true after the getopt switch; unless the -K option is
16957416Smarkm	 * passed
17057416Smarkm	 */
17157416Smarkm	autologin = -1;
17257416Smarkm
17357416Smarkm	while((ch = getopt(argc, argv,
17457416Smarkm			   "78DEKLS:X:abcde:fFk:l:n:rxG")) != -1) {
17557416Smarkm		switch(ch) {
17657416Smarkm		case '8':
17757416Smarkm			eight = 3;	/* binary output and input */
17857416Smarkm			break;
17957416Smarkm		case '7':
18057416Smarkm			eight = 0;
18157416Smarkm			break;
18257416Smarkm		case 'b':
18357416Smarkm		    binary = 3;
18457416Smarkm		    break;
18557416Smarkm		case 'D': {
18657416Smarkm		    /* sometimes we don't want a mangled display */
18757416Smarkm		    char *p;
18857416Smarkm		    if((p = getenv("DISPLAY")))
18990926Snectar			env_define((unsigned char*)"DISPLAY", (unsigned char*)p);
19057416Smarkm		    break;
19157416Smarkm		}
19257416Smarkm		case 'E':
19357416Smarkm			rlogin = escape = _POSIX_VDISABLE;
19457416Smarkm			break;
19557416Smarkm		case 'K':
19657416Smarkm#ifdef	AUTHENTICATION
19757416Smarkm			autologin = 0;
19857416Smarkm#endif
19957416Smarkm			break;
20057416Smarkm		case 'L':
20157416Smarkm			eight |= 2;	/* binary output only */
20257416Smarkm			break;
20357416Smarkm		case 'S':
20457416Smarkm		    {
20557416Smarkm#ifdef	HAVE_PARSETOS
20657416Smarkm			extern int tos;
20757416Smarkm
20857416Smarkm			if ((tos = parsetos(optarg, "tcp")) < 0)
20957416Smarkm				fprintf(stderr, "%s%s%s%s\n",
21057416Smarkm					prompt, ": Bad TOS argument '",
21157416Smarkm					optarg,
21257416Smarkm					"; will try to use default TOS");
21357416Smarkm#else
21457416Smarkm			fprintf(stderr,
21557416Smarkm			   "%s: Warning: -S ignored, no parsetos() support.\n",
21657416Smarkm								prompt);
21757416Smarkm#endif
21857416Smarkm		    }
21957416Smarkm			break;
22057416Smarkm		case 'X':
22157416Smarkm#ifdef	AUTHENTICATION
22257416Smarkm			auth_disable_name(optarg);
22357416Smarkm#endif
22457416Smarkm			break;
22557416Smarkm		case 'a':
22657416Smarkm			autologin = 1;
22757416Smarkm			break;
22857416Smarkm		case 'c':
22957416Smarkm			skiprc = 1;
23057416Smarkm			break;
23157416Smarkm		case 'd':
23257416Smarkm			debug = 1;
23357416Smarkm			break;
23457416Smarkm		case 'e':
23557416Smarkm			set_escape_char(optarg);
23657416Smarkm			break;
23757416Smarkm		case 'f':
23857416Smarkm#if defined(AUTHENTICATION) && defined(KRB5) && defined(FORWARD)
23957416Smarkm			if ((forward_flags & OPTS_FORWARD_CREDS) &&
24057416Smarkm			    !default_forward) {
24157416Smarkm			    fprintf(stderr,
24257416Smarkm				    "%s: Only one of -f and -F allowed.\n",
24357416Smarkm				    prompt);
24457416Smarkm			    usage();
24557416Smarkm			}
24657416Smarkm			forward_flags |= OPTS_FORWARD_CREDS;
24757416Smarkm#else
24857416Smarkm			fprintf(stderr,
24957416Smarkm			 "%s: Warning: -f ignored, no Kerberos V5 support.\n",
25057416Smarkm				prompt);
25157416Smarkm#endif
25257416Smarkm			break;
25357416Smarkm		case 'F':
25457416Smarkm#if defined(AUTHENTICATION) && defined(KRB5) && defined(FORWARD)
25557416Smarkm			if ((forward_flags & OPTS_FORWARD_CREDS) &&
25657416Smarkm			    !default_forward) {
25757416Smarkm			    fprintf(stderr,
25857416Smarkm				    "%s: Only one of -f and -F allowed.\n",
25957416Smarkm				    prompt);
26057416Smarkm			    usage();
26157416Smarkm			}
26257416Smarkm			forward_flags |= OPTS_FORWARD_CREDS;
26357416Smarkm			forward_flags |= OPTS_FORWARDABLE_CREDS;
26457416Smarkm#else
26557416Smarkm			fprintf(stderr,
26657416Smarkm			 "%s: Warning: -F ignored, no Kerberos V5 support.\n",
26757416Smarkm				prompt);
26857416Smarkm#endif
26957416Smarkm			break;
27057416Smarkm		case 'k':
27157416Smarkm#if defined(AUTHENTICATION) && defined(KRB4)
27257416Smarkm		    {
27357416Smarkm			dest_realm = dst_realm_buf;
27457416Smarkm			strlcpy(dest_realm, optarg, dst_realm_sz);
27557416Smarkm		    }
27657416Smarkm#else
27757416Smarkm			fprintf(stderr,
27857416Smarkm			   "%s: Warning: -k ignored, no Kerberos V4 support.\n",
27957416Smarkm								prompt);
28057416Smarkm#endif
28157416Smarkm			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		case 'G':
30857416Smarkm#if defined(AUTHENTICATION) && defined(KRB5) && defined(FORWARD)
30957416Smarkm                        forward_flags ^= OPTS_FORWARD_CREDS;
31057416Smarkm                        forward_flags ^= OPTS_FORWARDABLE_CREDS;
31157416Smarkm#else
31257416Smarkm                        fprintf(stderr,
31357416Smarkm                         "%s: Warning: -G ignored, no Kerberos V5 support.\n",
31457416Smarkm                                prompt);
31557416Smarkm#endif
31657416Smarkm                        break;
31757416Smarkm
31857416Smarkm		case '?':
31957416Smarkm		default:
32057416Smarkm			usage();
32157416Smarkm			/* NOTREACHED */
32257416Smarkm		}
32357416Smarkm	}
32457416Smarkm
32557416Smarkm	if (autologin == -1) {		/* esc@magic.fi; force  */
32657416Smarkm#if defined(AUTHENTICATION)
32757416Smarkm		autologin = 1;
32857416Smarkm#endif
32957416Smarkm#if defined(ENCRYPTION)
33057416Smarkm		encrypt_auto(1);
33157416Smarkm		decrypt_auto(1);
33257416Smarkm#endif
33357416Smarkm	}
33457416Smarkm
33557416Smarkm	if (autologin == -1)
33657416Smarkm		autologin = (rlogin == _POSIX_VDISABLE) ? 0 : 1;
33757416Smarkm
33857416Smarkm	argc -= optind;
33957416Smarkm	argv += optind;
34057416Smarkm
34157416Smarkm	if (argc) {
34257416Smarkm		char *args[7], **argp = args;
34357416Smarkm
34457416Smarkm		if (argc > 2)
34557416Smarkm			usage();
34657416Smarkm		*argp++ = prompt;
34757416Smarkm		if (user) {
34857416Smarkm			*argp++ = "-l";
34957416Smarkm			*argp++ = user;
35057416Smarkm		}
35157416Smarkm		*argp++ = argv[0];		/* host */
35257416Smarkm		if (argc > 1)
35357416Smarkm			*argp++ = argv[1];	/* port */
35457416Smarkm		*argp = 0;
35557416Smarkm
35657416Smarkm		if (setjmp(toplevel) != 0)
35757416Smarkm			Exit(0);
35857416Smarkm		if (tn(argp - args, args) == 1)
35957416Smarkm			return (0);
36057416Smarkm		else
36157416Smarkm			return (1);
36257416Smarkm	}
36357416Smarkm	setjmp(toplevel);
36457416Smarkm	for (;;) {
36557416Smarkm			command(1, 0, 0);
36657416Smarkm	}
36757416Smarkm}
368