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