main.c revision 127808
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
34static char *copyright[] = {
35    "@(#) Copyright (c) 1988, 1990, 1993\n"
36    "\tThe Regents of the University of California.  All rights reserved.\n",
37    (char*)copyright
38};
39
40#include "telnet_locl.h"
41RCSID("$Id: main.c,v 1.38.6.1 2004/03/22 18:16:35 lha Exp $");
42
43#if KRB5
44#define FORWARD
45#endif
46
47/*
48 * Initialize variables.
49 */
50void
51tninit(void)
52{
53    init_terminal();
54
55    init_network();
56
57    init_telnet();
58
59    init_sys();
60}
61
62void
63usage(void)
64{
65  fprintf(stderr, "Usage: %s %s%s%s%s\n", prompt,
66#ifdef	AUTHENTICATION
67	  "[-8] [-E] [-K] [-L] [-G] [-S tos] [-X atype] [-a] [-c] [-d] [-e char]",
68	  "\n\t[-k realm] [-l user] [-f/-F] [-n tracefile] ",
69#else
70	  "[-8] [-E] [-L] [-S tos] [-a] [-c] [-d] [-e char] [-l user]",
71	  "\n\t[-n tracefile]",
72#endif
73	  "[-r] ",
74#ifdef	ENCRYPTION
75	  "[-x] [host-name [port]]"
76#else
77	  "[host-name [port]]"
78#endif
79    );
80  exit(1);
81}
82
83/*
84 * main.  Parse arguments, invoke the protocol or command parser.
85 */
86
87
88#ifdef	FORWARD
89int forward_option = 0; /* forward flags set from command line */
90#endif	/* FORWARD */
91void
92set_forward_options(void)
93{
94#ifdef FORWARD
95	switch(forward_option) {
96	case 'f':
97		kerberos5_set_forward(1);
98		kerberos5_set_forwardable(0);
99		break;
100	case 'F':
101		kerberos5_set_forward(1);
102		kerberos5_set_forwardable(1);
103		break;
104	case 'G':
105		kerberos5_set_forward(0);
106		kerberos5_set_forwardable(0);
107		break;
108	default:
109		break;
110	}
111#endif
112}
113
114#ifdef KRB5
115/* XXX ugly hack to setup dns-proxy stuff */
116#define Authenticator asn1_Authenticator
117#include <krb5.h>
118static void
119krb5_init(void)
120{
121    krb5_context context;
122    krb5_error_code ret;
123
124    ret = krb5_init_context(&context);
125    if (ret)
126	return;
127
128#if defined(AUTHENTICATION) && defined(KRB5) && defined(FORWARD)
129    if (krb5_config_get_bool (context, NULL,
130         "libdefaults", "forward", NULL)) {
131	    kerberos5_set_forward(1);
132    }
133    if (krb5_config_get_bool (context, NULL,
134         "libdefaults", "forwardable", NULL)) {
135	    kerberos5_set_forwardable(1);
136    }
137#endif
138#ifdef  ENCRYPTION
139    if (krb5_config_get_bool (context, NULL,
140        "libdefaults", "encrypt", NULL)) {
141          encrypt_auto(1);
142          decrypt_auto(1);
143	  wantencryption = 1;
144          EncryptVerbose(1);
145        }
146#endif
147
148    krb5_free_context(context);
149}
150#endif
151
152#if defined(AUTHENTICATION) && defined(KRB4)
153extern char *dest_realm, dst_realm_buf[];
154extern int dst_realm_sz;
155#endif
156
157int
158main(int argc, char **argv)
159{
160	int ch;
161	char *user;
162
163	setprogname(argv[0]);
164
165#ifdef KRB5
166	krb5_init();
167#endif
168
169	tninit();		/* Clear out things */
170
171	TerminalSaveState();
172
173	if ((prompt = strrchr(argv[0], '/')))
174		++prompt;
175	else
176		prompt = argv[0];
177
178	user = NULL;
179
180	rlogin = (strncmp(prompt, "rlog", 4) == 0) ? '~' : _POSIX_VDISABLE;
181
182	/*
183	 * if AUTHENTICATION and ENCRYPTION is set autologin will be
184	 * se to true after the getopt switch; unless the -K option is
185	 * passed
186	 */
187	autologin = -1;
188
189	if (argc == 2 && strcmp(argv[1], "--version") == 0) {
190	    print_version(NULL);
191	    exit(0);
192	}
193
194	while((ch = getopt(argc, argv,
195			   "78DEKLS:X:abcde:fFk:l:n:rxG")) != -1) {
196		switch(ch) {
197		case '8':
198			eight = 3;	/* binary output and input */
199			break;
200		case '7':
201			eight = 0;
202			break;
203		case 'b':
204		    binary = 3;
205		    break;
206		case 'D': {
207		    /* sometimes we don't want a mangled display */
208		    char *p;
209		    if((p = getenv("DISPLAY")))
210			env_define((unsigned char*)"DISPLAY", (unsigned char*)p);
211		    break;
212		}
213		case 'E':
214			rlogin = escape = _POSIX_VDISABLE;
215			break;
216		case 'K':
217#ifdef	AUTHENTICATION
218			autologin = 0;
219#endif
220			break;
221		case 'L':
222			eight |= 2;	/* binary output only */
223			break;
224		case 'S':
225		    {
226#ifdef	HAVE_PARSETOS
227			extern int tos;
228
229			if ((tos = parsetos(optarg, "tcp")) < 0)
230				fprintf(stderr, "%s%s%s%s\n",
231					prompt, ": Bad TOS argument '",
232					optarg,
233					"; will try to use default TOS");
234#else
235			fprintf(stderr,
236			   "%s: Warning: -S ignored, no parsetos() support.\n",
237								prompt);
238#endif
239		    }
240			break;
241		case 'X':
242#ifdef	AUTHENTICATION
243			auth_disable_name(optarg);
244#endif
245			break;
246		case 'a':
247			autologin = 1;
248			break;
249		case 'c':
250			skiprc = 1;
251			break;
252		case 'd':
253			debug = 1;
254			break;
255		case 'e':
256			set_escape_char(optarg);
257			break;
258		case 'f':
259		case 'F':
260		case 'G':
261#if defined(AUTHENTICATION) && defined(KRB5) && defined(FORWARD)
262			if (forward_option) {
263			    fprintf(stderr,
264				    "%s: Only one of -f, -F and -G allowed.\n",
265				    prompt);
266			    usage();
267			}
268			forward_option = ch;
269#else
270			fprintf(stderr,
271			 "%s: Warning: -%c ignored, no Kerberos V5 support.\n",
272				prompt, ch);
273#endif
274			break;
275		case 'k':
276#if defined(AUTHENTICATION) && defined(KRB4)
277		    {
278			dest_realm = dst_realm_buf;
279			strlcpy(dest_realm, optarg, dst_realm_sz);
280		    }
281#else
282			fprintf(stderr,
283			   "%s: Warning: -k ignored, no Kerberos V4 support.\n",
284								prompt);
285#endif
286			break;
287		case 'l':
288		  if(autologin == 0){
289		    fprintf(stderr, "%s: Warning: -K ignored\n", prompt);
290		    autologin = -1;
291		  }
292			user = optarg;
293			break;
294		case 'n':
295				SetNetTrace(optarg);
296			break;
297		case 'r':
298			rlogin = '~';
299			break;
300		case 'x':
301#ifdef	ENCRYPTION
302			encrypt_auto(1);
303			decrypt_auto(1);
304			wantencryption = 1;
305			EncryptVerbose(1);
306#else
307			fprintf(stderr,
308			    "%s: Warning: -x ignored, no ENCRYPT support.\n",
309								prompt);
310#endif
311			break;
312
313		case '?':
314		default:
315			usage();
316			/* NOTREACHED */
317		}
318	}
319
320	if (autologin == -1) {		/* esc@magic.fi; force  */
321#if defined(AUTHENTICATION)
322		autologin = 1;
323#endif
324#if defined(ENCRYPTION)
325		encrypt_auto(1);
326		decrypt_auto(1);
327		wantencryption = -1;
328#endif
329	}
330
331	if (autologin == -1)
332		autologin = (rlogin == _POSIX_VDISABLE) ? 0 : 1;
333
334	argc -= optind;
335	argv += optind;
336
337	if (argc) {
338		char *args[7], **argp = args;
339
340		if (argc > 2)
341			usage();
342		*argp++ = prompt;
343		if (user) {
344			*argp++ = "-l";
345			*argp++ = user;
346		}
347		*argp++ = argv[0];		/* host */
348		if (argc > 1)
349			*argp++ = argv[1];	/* port */
350		*argp = 0;
351
352		if (setjmp(toplevel) != 0)
353			Exit(0);
354		if (tn(argp - args, args) == 1)
355			return (0);
356		else
357			return (1);
358	}
359	setjmp(toplevel);
360	for (;;) {
361			command(1, 0, 0);
362	}
363}
364