xref: /openbsd-src/usr.bin/telnet/main.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
1 /*	$OpenBSD: main.c,v 1.11 2001/05/25 10:24:25 hin Exp $	*/
2 /*	$NetBSD: main.c,v 1.5 1996/02/28 21:04:05 thorpej Exp $	*/
3 
4 /*
5  * Copyright (c) 1988, 1990, 1993
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *	This product includes software developed by the University of
19  *	California, Berkeley and its contributors.
20  * 4. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  */
36 
37 #ifndef lint
38 static char copyright[] =
39 "@(#) Copyright (c) 1988, 1990, 1993\n\
40 	The Regents of the University of California.  All rights reserved.\n";
41 #endif /* not lint */
42 
43 #include "telnet_locl.h"
44 
45 /* These values need to be the same as defined in libtelnet/kerberos5.c */
46 /* Either define them in both places, or put in some common header file. */
47 #define OPTS_FORWARD_CREDS	0x00000002
48 #define OPTS_FORWARDABLE_CREDS	0x00000001
49 
50 #ifdef KRB5
51 #define FORWARD
52 /* XXX ugly hack to setup dns-proxy stuff */
53 #define Authenticator asn1_Authenticator
54 #include <kerberosV/krb5.h>
55 #endif
56 
57 #ifdef KRB4
58 #include <kerberosIV/krb.h>
59 #endif
60 
61 #ifdef FORWARD
62 int forward_flags;
63 static int default_forward=0;
64 #endif
65 
66 /*
67  * Initialize variables.
68  */
69     void
70 tninit()
71 {
72     init_terminal();
73 
74     init_network();
75 
76     init_telnet();
77 
78     init_sys();
79 
80 #if defined(TN3270)
81     init_3270();
82 #endif
83 }
84 
85 	void
86 usage()
87 {
88 	fprintf(stderr, "Usage: %s %s%s%s%s\n",
89 	    prompt,
90 #ifdef	AUTHENTICATION
91 	    "[-8] [-E] [-K] [-L] [-S tos] [-X atype] [-a] [-c] [-d] [-e char]",
92 	    "\n\t[-k realm] [-l user] [-f/-F] [-n tracefile] [-b hostalias ] ",
93 #else
94 	    "[-8] [-E] [-L] [-S tos] [-a] [-c] [-d] [-e char] [-l user]",
95 	    "\n\t[-n tracefile] [-b hostalias ] ",
96 #endif
97 #if defined(TN3270) && defined(unix)
98 # ifdef AUTHENTICATION
99 	    "[-noasynch] [-noasynctty]\n\t[-noasyncnet] [-r] [-t transcom] ",
100 # else
101 	    "[-noasynch] [-noasynctty] [-noasyncnet] [-r]\n\t[-t transcom]",
102 # endif
103 #else
104 	    "[-r] ",
105 #endif
106 	    "\n\t"
107 #ifdef ENCRYPTION
108 	    "[-x] "
109 #endif
110 	    "[host-name [port]]");
111 	exit(1);
112 }
113 
114 
115 #ifdef KRB5
116 static void
117 krb5_init(void)
118 {
119     krb5_context context;
120     krb5_error_code ret;
121 
122     ret = krb5_init_context(&context);
123     if (ret)
124 	return;
125 
126 #if defined(AUTHENTICATION) && defined(KRB5) && defined(FORWARD)
127     if (krb5_config_get_bool (context, NULL,
128          "libdefaults", "forward", NULL)) {
129            forward_flags |= OPTS_FORWARD_CREDS;
130            default_forward=1;
131     }
132     if (krb5_config_get_bool (context, NULL,
133          "libdefaults", "forwardable", NULL)) {
134            forward_flags |= OPTS_FORWARDABLE_CREDS;
135            default_forward=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           EncryptVerbose(1);
144         }
145 #endif
146 
147     krb5_free_context(context);
148 }
149 #endif
150 
151 /*
152  * main.  Parse arguments, invoke the protocol or command parser.
153  */
154 
155 	int
156 main(argc, argv)
157 	int argc;
158 	char *argv[];
159 {
160 	extern char *optarg;
161 	extern int optind;
162 	int ch;
163 	char *user, *alias;
164 #ifdef	FORWARD
165 	extern int forward_flags;
166 #endif	/* FORWARD */
167 
168 #ifdef KRB5
169 	krb5_init();
170 #endif
171 
172 	tninit();		/* Clear out things */
173 
174 	TerminalSaveState();
175 
176 	if ((prompt = strrchr(argv[0], '/')))
177 		++prompt;
178 	else
179 		prompt = argv[0];
180 
181 	user = alias = NULL;
182 
183 	rlogin = (strncmp(prompt, "rlog", 4) == 0) ? '~' : _POSIX_VDISABLE;
184 
185 	/*
186 	 * if AUTHENTICATION and ENCRYPTION is set autologin will be
187 	 * set to true after the getopt switch; unless the -K option is
188 	 * passed
189 	 */
190 	autologin = -1;
191 
192 	while ((ch = getopt(argc, argv, "78DEKLS:X:ab:cde:fFk:l:n:rt:x")) != -1) {
193 		switch(ch) {
194 		case '8':
195 			eight = 3;	/* binary output and input */
196 			break;
197 		case '7':
198 			eight = 0;
199 			break;
200 		case 'D': {
201 			/* sometimes we don't want a mangled display */
202 			char *p;
203 			if((p = getenv("DISPLAY")))
204 				env_define("DISPLAY", (unsigned char*)p);
205 			break;
206 		}
207 
208 		case 'E':
209 			rlogin = escape = _POSIX_VDISABLE;
210 			break;
211 		case 'K':
212 #ifdef	AUTHENTICATION
213 			autologin = 0;
214 #endif
215 			break;
216 		case 'L':
217 			eight |= 2;	/* binary output only */
218 			break;
219 		case 'S':
220 		    {
221 #ifdef	HAS_GETTOS
222 			extern int tos;
223 
224 			if ((tos = parsetos(optarg, "tcp")) < 0)
225 				fprintf(stderr, "%s%s%s%s\n",
226 					prompt, ": Bad TOS argument '",
227 					optarg,
228 					"; will try to use default TOS");
229 #else
230 			fprintf(stderr,
231 			   "%s: Warning: -S ignored, no parsetos() support.\n",
232 								prompt);
233 #endif
234 		    }
235 			break;
236 		case 'X':
237 #ifdef	AUTHENTICATION
238 			auth_disable_name(optarg);
239 #endif
240 			break;
241 		case 'a':
242 			autologin = 1;
243 			break;
244 		case 'c':
245 			skiprc = 1;
246 			break;
247 		case 'd':
248 			debug = 1;
249 			break;
250 		case 'e':
251 			set_escape_char(optarg);
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 #else
264 			fprintf(stderr,
265 			 "%s: Warning: -f ignored, no Kerberos V5 support.\n",
266 				prompt);
267 #endif
268 			break;
269 		case 'F':
270 #if defined(AUTHENTICATION) && defined(KRB5) && defined(FORWARD)
271 			if ((forward_flags & OPTS_FORWARD_CREDS) &&
272 			    !default_forward) {
273 			    fprintf(stderr,
274 				    "%s: Only one of -f and -F allowed.\n",
275 				    prompt);
276 			    usage();
277 			}
278 			forward_flags |= OPTS_FORWARD_CREDS;
279 			forward_flags |= OPTS_FORWARDABLE_CREDS;
280 #else
281 			fprintf(stderr,
282 			 "%s: Warning: -F ignored, no Kerberos V5 support.\n",
283 				prompt);
284 #endif
285 			break;
286 		case 'k':
287 #if defined(AUTHENTICATION) && defined(KRB4)
288 		    {
289 			extern char *dest_realm, dst_realm_buf[];
290 			extern int dst_realm_sz;
291 			dest_realm = dst_realm_buf;
292 			(void)strncpy(dest_realm, optarg, dst_realm_sz);
293 		    }
294 #else
295 			fprintf(stderr,
296 			   "%s: Warning: -k ignored, no Kerberos V4 support.\n",
297 								prompt);
298 #endif
299 			break;
300 		case 'l':
301 			autologin = -1;
302 			user = optarg;
303 			break;
304 		case 'b':
305 			alias = optarg;
306 			break;
307 		case 'n':
308 #if defined(TN3270) && defined(unix)
309 			/* distinguish between "-n oasynch" and "-noasynch" */
310 			if (argv[optind - 1][0] == '-' && argv[optind - 1][1]
311 			    == 'n' && argv[optind - 1][2] == 'o') {
312 				if (!strcmp(optarg, "oasynch")) {
313 					noasynchtty = 1;
314 					noasynchnet = 1;
315 				} else if (!strcmp(optarg, "oasynchtty"))
316 					noasynchtty = 1;
317 				else if (!strcmp(optarg, "oasynchnet"))
318 					noasynchnet = 1;
319 			} else
320 #endif	/* defined(TN3270) && defined(unix) */
321 				SetNetTrace(optarg);
322 			break;
323 		case 'r':
324 			rlogin = '~';
325 			break;
326 		case 't':
327 #if defined(TN3270) && defined(unix)
328 			(void)strlcpy(tline, optarg, sizeof tline);
329 			transcom = tline;
330 #else
331 			fprintf(stderr,
332 			   "%s: Warning: -t ignored, no TN3270 support.\n",
333 								prompt);
334 #endif
335 			break;
336 		case 'x':
337 #ifdef ENCRYPTION
338 			encrypt_auto(1);
339 			decrypt_auto(1);
340 			EncryptVerbose(1);
341 #else
342 			fprintf(stderr,
343 			    "%s: Warning: -x ignored, no ENCRYPT support.\n",
344 								prompt);
345 #endif
346 			break;
347 		case '?':
348 		default:
349 			usage();
350 			/* NOTREACHED */
351 		}
352 	}
353 
354 	if (autologin == -1) {
355 #if defined(AUTHENTICATION)
356 		autologin = 1;
357 #endif
358 #if defined(ENCRYPTION)
359 		encrypt_auto(1);
360 		decrypt_auto(1);
361 #endif
362 	}
363 
364 	if (autologin == -1)
365 		autologin = (rlogin == _POSIX_VDISABLE) ? 0 : 1;
366 
367 	argc -= optind;
368 	argv += optind;
369 
370 	if (argc) {
371 		char *args[7], **argp = args;
372 
373 		if (argc > 2)
374 			usage();
375 		*argp++ = prompt;
376 		if (user) {
377 			*argp++ = "-l";
378 			*argp++ = user;
379 		}
380 		if (alias) {
381 			*argp++ = "-b";
382 			*argp++ = alias;
383 		}
384 		*argp++ = argv[0];		/* host */
385 		if (argc > 1)
386 			*argp++ = argv[1];	/* port */
387 		*argp = 0;
388 
389 		if (setjmp(toplevel) != 0)
390 			Exit(0);
391 		if (tn(argp - args, args) == 1)
392 			return (0);
393 		else
394 			return (1);
395 	}
396 	(void)setjmp(toplevel);
397 	for (;;) {
398 #ifdef TN3270
399 		if (shell_active)
400 			shell_continue();
401 		else
402 #endif
403 			command(1, 0, 0);
404 	}
405 	return 0;
406 }
407