main.c revision 102644
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 2002/08/28 21:05:22 joda 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#ifdef KRB5
164	krb5_init();
165#endif
166
167	tninit();		/* Clear out things */
168
169	TerminalSaveState();
170
171	if ((prompt = strrchr(argv[0], '/')))
172		++prompt;
173	else
174		prompt = argv[0];
175
176	user = NULL;
177
178	rlogin = (strncmp(prompt, "rlog", 4) == 0) ? '~' : _POSIX_VDISABLE;
179
180	/*
181	 * if AUTHENTICATION and ENCRYPTION is set autologin will be
182	 * se to true after the getopt switch; unless the -K option is
183	 * passed
184	 */
185	autologin = -1;
186
187	if (argc == 2 && strcmp(argv[1], "--version") == 0) {
188	    print_version(NULL);
189	    exit(0);
190	}
191
192	while((ch = getopt(argc, argv,
193			   "78DEKLS:X:abcde:fFk:l:n:rxG")) != -1) {
194		switch(ch) {
195		case '8':
196			eight = 3;	/* binary output and input */
197			break;
198		case '7':
199			eight = 0;
200			break;
201		case 'b':
202		    binary = 3;
203		    break;
204		case 'D': {
205		    /* sometimes we don't want a mangled display */
206		    char *p;
207		    if((p = getenv("DISPLAY")))
208			env_define((unsigned char*)"DISPLAY", (unsigned char*)p);
209		    break;
210		}
211		case 'E':
212			rlogin = escape = _POSIX_VDISABLE;
213			break;
214		case 'K':
215#ifdef	AUTHENTICATION
216			autologin = 0;
217#endif
218			break;
219		case 'L':
220			eight |= 2;	/* binary output only */
221			break;
222		case 'S':
223		    {
224#ifdef	HAVE_PARSETOS
225			extern int tos;
226
227			if ((tos = parsetos(optarg, "tcp")) < 0)
228				fprintf(stderr, "%s%s%s%s\n",
229					prompt, ": Bad TOS argument '",
230					optarg,
231					"; will try to use default TOS");
232#else
233			fprintf(stderr,
234			   "%s: Warning: -S ignored, no parsetos() support.\n",
235								prompt);
236#endif
237		    }
238			break;
239		case 'X':
240#ifdef	AUTHENTICATION
241			auth_disable_name(optarg);
242#endif
243			break;
244		case 'a':
245			autologin = 1;
246			break;
247		case 'c':
248			skiprc = 1;
249			break;
250		case 'd':
251			debug = 1;
252			break;
253		case 'e':
254			set_escape_char(optarg);
255			break;
256		case 'f':
257		case 'F':
258		case 'G':
259#if defined(AUTHENTICATION) && defined(KRB5) && defined(FORWARD)
260			if (forward_option) {
261			    fprintf(stderr,
262				    "%s: Only one of -f, -F and -G allowed.\n",
263				    prompt);
264			    usage();
265			}
266			forward_option = ch;
267#else
268			fprintf(stderr,
269			 "%s: Warning: -%c ignored, no Kerberos V5 support.\n",
270				prompt, ch);
271#endif
272			break;
273		case 'k':
274#if defined(AUTHENTICATION) && defined(KRB4)
275		    {
276			dest_realm = dst_realm_buf;
277			strlcpy(dest_realm, optarg, dst_realm_sz);
278		    }
279#else
280			fprintf(stderr,
281			   "%s: Warning: -k ignored, no Kerberos V4 support.\n",
282								prompt);
283#endif
284			break;
285		case 'l':
286		  if(autologin == 0){
287		    fprintf(stderr, "%s: Warning: -K ignored\n", prompt);
288		    autologin = -1;
289		  }
290			user = optarg;
291			break;
292		case 'n':
293				SetNetTrace(optarg);
294			break;
295		case 'r':
296			rlogin = '~';
297			break;
298		case 'x':
299#ifdef	ENCRYPTION
300			encrypt_auto(1);
301			decrypt_auto(1);
302			wantencryption = 1;
303			EncryptVerbose(1);
304#else
305			fprintf(stderr,
306			    "%s: Warning: -x ignored, no ENCRYPT support.\n",
307								prompt);
308#endif
309			break;
310
311		case '?':
312		default:
313			usage();
314			/* NOTREACHED */
315		}
316	}
317
318	if (autologin == -1) {		/* esc@magic.fi; force  */
319#if defined(AUTHENTICATION)
320		autologin = 1;
321#endif
322#if defined(ENCRYPTION)
323		encrypt_auto(1);
324		decrypt_auto(1);
325		wantencryption = -1;
326#endif
327	}
328
329	if (autologin == -1)
330		autologin = (rlogin == _POSIX_VDISABLE) ? 0 : 1;
331
332	argc -= optind;
333	argv += optind;
334
335	if (argc) {
336		char *args[7], **argp = args;
337
338		if (argc > 2)
339			usage();
340		*argp++ = prompt;
341		if (user) {
342			*argp++ = "-l";
343			*argp++ = user;
344		}
345		*argp++ = argv[0];		/* host */
346		if (argc > 1)
347			*argp++ = argv[1];	/* port */
348		*argp = 0;
349
350		if (setjmp(toplevel) != 0)
351			Exit(0);
352		if (tn(argp - args, args) == 1)
353			return (0);
354		else
355			return (1);
356	}
357	setjmp(toplevel);
358	for (;;) {
359			command(1, 0, 0);
360	}
361}
362