xref: /freebsd/crypto/heimdal/appl/telnet/telnet/main.c (revision 6a068746777241722b2b32c5d0bc443a2a64d80b)
113e3f4d6SMark Murray /*
213e3f4d6SMark Murray  * Copyright (c) 1988, 1990, 1993
313e3f4d6SMark Murray  *	The Regents of the University of California.  All rights reserved.
413e3f4d6SMark Murray  *
513e3f4d6SMark Murray  * Redistribution and use in source and binary forms, with or without
613e3f4d6SMark Murray  * modification, are permitted provided that the following conditions
713e3f4d6SMark Murray  * are met:
813e3f4d6SMark Murray  * 1. Redistributions of source code must retain the above copyright
913e3f4d6SMark Murray  *    notice, this list of conditions and the following disclaimer.
1013e3f4d6SMark Murray  * 2. Redistributions in binary form must reproduce the above copyright
1113e3f4d6SMark Murray  *    notice, this list of conditions and the following disclaimer in the
1213e3f4d6SMark Murray  *    documentation and/or other materials provided with the distribution.
1313e3f4d6SMark Murray  * 3. All advertising materials mentioning features or use of this software
1413e3f4d6SMark Murray  *    must display the following acknowledgement:
1513e3f4d6SMark Murray  *	This product includes software developed by the University of
1613e3f4d6SMark Murray  *	California, Berkeley and its contributors.
1713e3f4d6SMark Murray  * 4. Neither the name of the University nor the names of its contributors
1813e3f4d6SMark Murray  *    may be used to endorse or promote products derived from this software
1913e3f4d6SMark Murray  *    without specific prior written permission.
2013e3f4d6SMark Murray  *
2113e3f4d6SMark Murray  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2213e3f4d6SMark Murray  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2313e3f4d6SMark Murray  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2413e3f4d6SMark Murray  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2513e3f4d6SMark Murray  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2613e3f4d6SMark Murray  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2713e3f4d6SMark Murray  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2813e3f4d6SMark Murray  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2913e3f4d6SMark Murray  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3013e3f4d6SMark Murray  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3113e3f4d6SMark Murray  * SUCH DAMAGE.
3213e3f4d6SMark Murray  */
3313e3f4d6SMark Murray 
3413e3f4d6SMark Murray static char *copyright[] = {
3513e3f4d6SMark Murray     "@(#) Copyright (c) 1988, 1990, 1993\n"
3613e3f4d6SMark Murray     "\tThe Regents of the University of California.  All rights reserved.\n",
3713e3f4d6SMark Murray     (char*)copyright
3813e3f4d6SMark Murray };
3913e3f4d6SMark Murray 
4013e3f4d6SMark Murray #include "telnet_locl.h"
41*ae771770SStanislav Sedov RCSID("$Id$");
4213e3f4d6SMark Murray 
4313e3f4d6SMark Murray #if KRB5
4413e3f4d6SMark Murray #define FORWARD
4513e3f4d6SMark Murray #endif
4613e3f4d6SMark Murray 
4713e3f4d6SMark Murray /*
4813e3f4d6SMark Murray  * Initialize variables.
4913e3f4d6SMark Murray  */
5013e3f4d6SMark Murray void
tninit(void)5113e3f4d6SMark Murray tninit(void)
5213e3f4d6SMark Murray {
5313e3f4d6SMark Murray     init_terminal();
5413e3f4d6SMark Murray 
5513e3f4d6SMark Murray     init_network();
5613e3f4d6SMark Murray 
5713e3f4d6SMark Murray     init_telnet();
5813e3f4d6SMark Murray 
5913e3f4d6SMark Murray     init_sys();
6013e3f4d6SMark Murray }
6113e3f4d6SMark Murray 
62c19800e8SDoug Rabson static void
usage(int exit_code)63c19800e8SDoug Rabson usage(int exit_code)
6413e3f4d6SMark Murray {
6513e3f4d6SMark Murray   fprintf(stderr, "Usage: %s %s%s%s%s\n", prompt,
6613e3f4d6SMark Murray #ifdef	AUTHENTICATION
6713e3f4d6SMark Murray 	  "[-8] [-E] [-K] [-L] [-G] [-S tos] [-X atype] [-a] [-c] [-d] [-e char]",
6813e3f4d6SMark Murray 	  "\n\t[-k realm] [-l user] [-f/-F] [-n tracefile] ",
6913e3f4d6SMark Murray #else
7013e3f4d6SMark Murray 	  "[-8] [-E] [-L] [-S tos] [-a] [-c] [-d] [-e char] [-l user]",
7113e3f4d6SMark Murray 	  "\n\t[-n tracefile]",
7213e3f4d6SMark Murray #endif
7313e3f4d6SMark Murray 	  "[-r] ",
7413e3f4d6SMark Murray #ifdef	ENCRYPTION
7513e3f4d6SMark Murray 	  "[-x] [host-name [port]]"
7613e3f4d6SMark Murray #else
7713e3f4d6SMark Murray 	  "[host-name [port]]"
7813e3f4d6SMark Murray #endif
7913e3f4d6SMark Murray     );
80c19800e8SDoug Rabson   exit(exit_code);
8113e3f4d6SMark Murray }
8213e3f4d6SMark Murray 
8313e3f4d6SMark Murray /*
8413e3f4d6SMark Murray  * main.  Parse arguments, invoke the protocol or command parser.
8513e3f4d6SMark Murray  */
8613e3f4d6SMark Murray 
8713e3f4d6SMark Murray 
8813e3f4d6SMark Murray #ifdef	FORWARD
898373020dSJacques Vidrine int forward_option = 0; /* forward flags set from command line */
9013e3f4d6SMark Murray #endif	/* FORWARD */
918373020dSJacques Vidrine void
set_forward_options(void)928373020dSJacques Vidrine set_forward_options(void)
938373020dSJacques Vidrine {
948373020dSJacques Vidrine #ifdef FORWARD
958373020dSJacques Vidrine 	switch(forward_option) {
968373020dSJacques Vidrine 	case 'f':
978373020dSJacques Vidrine 		kerberos5_set_forward(1);
988373020dSJacques Vidrine 		kerberos5_set_forwardable(0);
998373020dSJacques Vidrine 		break;
1008373020dSJacques Vidrine 	case 'F':
1018373020dSJacques Vidrine 		kerberos5_set_forward(1);
1028373020dSJacques Vidrine 		kerberos5_set_forwardable(1);
1038373020dSJacques Vidrine 		break;
1048373020dSJacques Vidrine 	case 'G':
1058373020dSJacques Vidrine 		kerberos5_set_forward(0);
1068373020dSJacques Vidrine 		kerberos5_set_forwardable(0);
1078373020dSJacques Vidrine 		break;
1088373020dSJacques Vidrine 	default:
1098373020dSJacques Vidrine 		break;
1108373020dSJacques Vidrine 	}
1118373020dSJacques Vidrine #endif
1128373020dSJacques Vidrine }
11313e3f4d6SMark Murray 
11413e3f4d6SMark Murray #ifdef KRB5
11513e3f4d6SMark Murray #define Authenticator asn1_Authenticator
11613e3f4d6SMark Murray #include <krb5.h>
11713e3f4d6SMark Murray static void
krb5_init(void)11813e3f4d6SMark Murray krb5_init(void)
11913e3f4d6SMark Murray {
12013e3f4d6SMark Murray     krb5_context context;
1215e9cd1aeSAssar Westerlund     krb5_error_code ret;
122c19800e8SDoug Rabson     krb5_boolean ret_val;
1235e9cd1aeSAssar Westerlund 
1245e9cd1aeSAssar Westerlund     ret = krb5_init_context(&context);
1255e9cd1aeSAssar Westerlund     if (ret)
1265e9cd1aeSAssar Westerlund 	return;
12713e3f4d6SMark Murray 
128c19800e8SDoug Rabson #if defined(AUTHENTICATION) && defined(FORWARD)
129c19800e8SDoug Rabson     krb5_appdefault_boolean(context, NULL,
130c19800e8SDoug Rabson 			    NULL, "forward",
131c19800e8SDoug Rabson 			    0, &ret_val);
132c19800e8SDoug Rabson     if (ret_val)
1338373020dSJacques Vidrine 	    kerberos5_set_forward(1);
134c19800e8SDoug Rabson     krb5_appdefault_boolean(context, NULL,
135c19800e8SDoug Rabson 			    NULL, "forwardable",
136c19800e8SDoug Rabson 			    0, &ret_val);
137c19800e8SDoug Rabson     if (ret_val)
1388373020dSJacques Vidrine 	    kerberos5_set_forwardable(1);
13913e3f4d6SMark Murray #endif
14013e3f4d6SMark Murray #ifdef  ENCRYPTION
141c19800e8SDoug Rabson     krb5_appdefault_boolean(context, NULL,
142c19800e8SDoug Rabson 			    NULL, "encrypt",
143c19800e8SDoug Rabson 			    0, &ret_val);
144c19800e8SDoug Rabson     if (ret_val) {
14513e3f4d6SMark Murray           encrypt_auto(1);
14613e3f4d6SMark Murray           decrypt_auto(1);
1474137ff4cSJacques Vidrine 	  wantencryption = 1;
14813e3f4d6SMark Murray           EncryptVerbose(1);
14913e3f4d6SMark Murray         }
15013e3f4d6SMark Murray #endif
15113e3f4d6SMark Murray 
15213e3f4d6SMark Murray     krb5_free_context(context);
15313e3f4d6SMark Murray }
15413e3f4d6SMark Murray #endif
15513e3f4d6SMark Murray 
15613e3f4d6SMark Murray int
main(int argc,char ** argv)15713e3f4d6SMark Murray main(int argc, char **argv)
15813e3f4d6SMark Murray {
15913e3f4d6SMark Murray 	int ch;
16013e3f4d6SMark Murray 	char *user;
16113e3f4d6SMark Murray 
1621c43270aSJacques Vidrine 	setprogname(argv[0]);
1631c43270aSJacques Vidrine 
16413e3f4d6SMark Murray #ifdef KRB5
16513e3f4d6SMark Murray 	krb5_init();
16613e3f4d6SMark Murray #endif
16713e3f4d6SMark Murray 
16813e3f4d6SMark Murray 	tninit();		/* Clear out things */
16913e3f4d6SMark Murray 
17013e3f4d6SMark Murray 	TerminalSaveState();
17113e3f4d6SMark Murray 
17213e3f4d6SMark Murray 	if ((prompt = strrchr(argv[0], '/')))
17313e3f4d6SMark Murray 		++prompt;
17413e3f4d6SMark Murray 	else
17513e3f4d6SMark Murray 		prompt = argv[0];
17613e3f4d6SMark Murray 
17713e3f4d6SMark Murray 	user = NULL;
17813e3f4d6SMark Murray 
17913e3f4d6SMark Murray 	rlogin = (strncmp(prompt, "rlog", 4) == 0) ? '~' : _POSIX_VDISABLE;
18013e3f4d6SMark Murray 
18113e3f4d6SMark Murray 	/*
18213e3f4d6SMark Murray 	 * if AUTHENTICATION and ENCRYPTION is set autologin will be
18313e3f4d6SMark Murray 	 * se to true after the getopt switch; unless the -K option is
18413e3f4d6SMark Murray 	 * passed
18513e3f4d6SMark Murray 	 */
18613e3f4d6SMark Murray 	autologin = -1;
18713e3f4d6SMark Murray 
1888373020dSJacques Vidrine 	if (argc == 2 && strcmp(argv[1], "--version") == 0) {
1898373020dSJacques Vidrine 	    print_version(NULL);
1908373020dSJacques Vidrine 	    exit(0);
1918373020dSJacques Vidrine 	}
192c19800e8SDoug Rabson 	if (argc == 2 && strcmp(argv[1], "--help") == 0)
193c19800e8SDoug Rabson 	    usage(0);
194c19800e8SDoug Rabson 
1958373020dSJacques Vidrine 
19613e3f4d6SMark Murray 	while((ch = getopt(argc, argv,
19713e3f4d6SMark Murray 			   "78DEKLS:X:abcde:fFk:l:n:rxG")) != -1) {
19813e3f4d6SMark Murray 		switch(ch) {
19913e3f4d6SMark Murray 		case '8':
20013e3f4d6SMark Murray 			eight = 3;	/* binary output and input */
20113e3f4d6SMark Murray 			break;
20213e3f4d6SMark Murray 		case '7':
20313e3f4d6SMark Murray 			eight = 0;
20413e3f4d6SMark Murray 			break;
20513e3f4d6SMark Murray 		case 'b':
20613e3f4d6SMark Murray 		    binary = 3;
20713e3f4d6SMark Murray 		    break;
20813e3f4d6SMark Murray 		case 'D': {
20913e3f4d6SMark Murray 		    /* sometimes we don't want a mangled display */
21013e3f4d6SMark Murray 		    char *p;
21113e3f4d6SMark Murray 		    if((p = getenv("DISPLAY")))
2124137ff4cSJacques Vidrine 			env_define((unsigned char*)"DISPLAY", (unsigned char*)p);
21313e3f4d6SMark Murray 		    break;
21413e3f4d6SMark Murray 		}
21513e3f4d6SMark Murray 		case 'E':
21613e3f4d6SMark Murray 			rlogin = escape = _POSIX_VDISABLE;
21713e3f4d6SMark Murray 			break;
21813e3f4d6SMark Murray 		case 'K':
21913e3f4d6SMark Murray #ifdef	AUTHENTICATION
22013e3f4d6SMark Murray 			autologin = 0;
22113e3f4d6SMark Murray #endif
22213e3f4d6SMark Murray 			break;
22313e3f4d6SMark Murray 		case 'L':
22413e3f4d6SMark Murray 			eight |= 2;	/* binary output only */
22513e3f4d6SMark Murray 			break;
22613e3f4d6SMark Murray 		case 'S':
22713e3f4d6SMark Murray 		    {
22813e3f4d6SMark Murray #ifdef	HAVE_PARSETOS
22913e3f4d6SMark Murray 			extern int tos;
23013e3f4d6SMark Murray 
23113e3f4d6SMark Murray 			if ((tos = parsetos(optarg, "tcp")) < 0)
23213e3f4d6SMark Murray 				fprintf(stderr, "%s%s%s%s\n",
23313e3f4d6SMark Murray 					prompt, ": Bad TOS argument '",
23413e3f4d6SMark Murray 					optarg,
23513e3f4d6SMark Murray 					"; will try to use default TOS");
23613e3f4d6SMark Murray #else
23713e3f4d6SMark Murray 			fprintf(stderr,
23813e3f4d6SMark Murray 			   "%s: Warning: -S ignored, no parsetos() support.\n",
23913e3f4d6SMark Murray 								prompt);
24013e3f4d6SMark Murray #endif
24113e3f4d6SMark Murray 		    }
24213e3f4d6SMark Murray 			break;
24313e3f4d6SMark Murray 		case 'X':
24413e3f4d6SMark Murray #ifdef	AUTHENTICATION
24513e3f4d6SMark Murray 			auth_disable_name(optarg);
24613e3f4d6SMark Murray #endif
24713e3f4d6SMark Murray 			break;
24813e3f4d6SMark Murray 		case 'a':
24913e3f4d6SMark Murray 			autologin = 1;
25013e3f4d6SMark Murray 			break;
25113e3f4d6SMark Murray 		case 'c':
25213e3f4d6SMark Murray 			skiprc = 1;
25313e3f4d6SMark Murray 			break;
25413e3f4d6SMark Murray 		case 'd':
25513e3f4d6SMark Murray 			debug = 1;
25613e3f4d6SMark Murray 			break;
25713e3f4d6SMark Murray 		case 'e':
25813e3f4d6SMark Murray 			set_escape_char(optarg);
25913e3f4d6SMark Murray 			break;
26013e3f4d6SMark Murray 		case 'f':
26113e3f4d6SMark Murray 		case 'F':
2628373020dSJacques Vidrine 		case 'G':
26313e3f4d6SMark Murray #if defined(AUTHENTICATION) && defined(KRB5) && defined(FORWARD)
2648373020dSJacques Vidrine 			if (forward_option) {
26513e3f4d6SMark Murray 			    fprintf(stderr,
2668373020dSJacques Vidrine 				    "%s: Only one of -f, -F and -G allowed.\n",
26713e3f4d6SMark Murray 				    prompt);
268c19800e8SDoug Rabson 			    usage(1);
26913e3f4d6SMark Murray 			}
2708373020dSJacques Vidrine 			forward_option = ch;
27113e3f4d6SMark Murray #else
27213e3f4d6SMark Murray 			fprintf(stderr,
2738373020dSJacques Vidrine 			 "%s: Warning: -%c ignored, no Kerberos V5 support.\n",
2748373020dSJacques Vidrine 				prompt, ch);
27513e3f4d6SMark Murray #endif
27613e3f4d6SMark Murray 			break;
27713e3f4d6SMark Murray 		case 'k':
27813e3f4d6SMark Murray 		    fprintf(stderr,
27913e3f4d6SMark Murray 			    "%s: Warning: -k ignored, no Kerberos V4 support.\n",
28013e3f4d6SMark Murray 			    prompt);
28113e3f4d6SMark Murray 		    break;
28213e3f4d6SMark Murray 		case 'l':
28313e3f4d6SMark Murray 		  if(autologin == 0){
28413e3f4d6SMark Murray 		    fprintf(stderr, "%s: Warning: -K ignored\n", prompt);
28513e3f4d6SMark Murray 		    autologin = -1;
28613e3f4d6SMark Murray 		  }
28713e3f4d6SMark Murray 			user = optarg;
28813e3f4d6SMark Murray 			break;
28913e3f4d6SMark Murray 		case 'n':
29013e3f4d6SMark Murray 				SetNetTrace(optarg);
29113e3f4d6SMark Murray 			break;
29213e3f4d6SMark Murray 		case 'r':
29313e3f4d6SMark Murray 			rlogin = '~';
29413e3f4d6SMark Murray 			break;
29513e3f4d6SMark Murray 		case 'x':
29613e3f4d6SMark Murray #ifdef	ENCRYPTION
29713e3f4d6SMark Murray 			encrypt_auto(1);
29813e3f4d6SMark Murray 			decrypt_auto(1);
2994137ff4cSJacques Vidrine 			wantencryption = 1;
30013e3f4d6SMark Murray 			EncryptVerbose(1);
30113e3f4d6SMark Murray #else
30213e3f4d6SMark Murray 			fprintf(stderr,
30313e3f4d6SMark Murray 			    "%s: Warning: -x ignored, no ENCRYPT support.\n",
30413e3f4d6SMark Murray 								prompt);
30513e3f4d6SMark Murray #endif
30613e3f4d6SMark Murray 			break;
30713e3f4d6SMark Murray 
30813e3f4d6SMark Murray 		case '?':
30913e3f4d6SMark Murray 		default:
310c19800e8SDoug Rabson 			usage(1);
31113e3f4d6SMark Murray 			/* NOTREACHED */
31213e3f4d6SMark Murray 		}
31313e3f4d6SMark Murray 	}
31413e3f4d6SMark Murray 
31513e3f4d6SMark Murray 	if (autologin == -1) {		/* esc@magic.fi; force  */
31613e3f4d6SMark Murray #if defined(AUTHENTICATION)
31713e3f4d6SMark Murray 		autologin = 1;
31813e3f4d6SMark Murray #endif
31913e3f4d6SMark Murray #if defined(ENCRYPTION)
32013e3f4d6SMark Murray 		encrypt_auto(1);
32113e3f4d6SMark Murray 		decrypt_auto(1);
3228373020dSJacques Vidrine 		wantencryption = -1;
32313e3f4d6SMark Murray #endif
32413e3f4d6SMark Murray 	}
32513e3f4d6SMark Murray 
32613e3f4d6SMark Murray 	if (autologin == -1)
32713e3f4d6SMark Murray 		autologin = (rlogin == _POSIX_VDISABLE) ? 0 : 1;
32813e3f4d6SMark Murray 
32913e3f4d6SMark Murray 	argc -= optind;
33013e3f4d6SMark Murray 	argv += optind;
33113e3f4d6SMark Murray 
33213e3f4d6SMark Murray 	if (argc) {
33313e3f4d6SMark Murray 		char *args[7], **argp = args;
33413e3f4d6SMark Murray 
33513e3f4d6SMark Murray 		if (argc > 2)
336c19800e8SDoug Rabson 			usage(1);
33713e3f4d6SMark Murray 		*argp++ = prompt;
33813e3f4d6SMark Murray 		if (user) {
33913e3f4d6SMark Murray 			*argp++ = "-l";
34013e3f4d6SMark Murray 			*argp++ = user;
34113e3f4d6SMark Murray 		}
34213e3f4d6SMark Murray 		*argp++ = argv[0];		/* host */
34313e3f4d6SMark Murray 		if (argc > 1)
34413e3f4d6SMark Murray 			*argp++ = argv[1];	/* port */
34513e3f4d6SMark Murray 		*argp = 0;
34613e3f4d6SMark Murray 
34713e3f4d6SMark Murray 		if (setjmp(toplevel) != 0)
34813e3f4d6SMark Murray 			Exit(0);
34913e3f4d6SMark Murray 		if (tn(argp - args, args) == 1)
35013e3f4d6SMark Murray 			return (0);
35113e3f4d6SMark Murray 		else
35213e3f4d6SMark Murray 			return (1);
35313e3f4d6SMark Murray 	}
35413e3f4d6SMark Murray 	setjmp(toplevel);
35513e3f4d6SMark Murray 	for (;;) {
35613e3f4d6SMark Murray 			command(1, 0, 0);
35713e3f4d6SMark Murray 	}
35813e3f4d6SMark Murray }
359