xref: /freebsd/crypto/heimdal/appl/telnet/telnet/main.c (revision b52b9d56d4e96089873a75f9e29062eec19fabba)
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 
34 static 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"
41 RCSID("$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  */
55 void
56 tninit(void)
57 {
58     init_terminal();
59 
60     init_network();
61 
62     init_telnet();
63 
64     init_sys();
65 }
66 
67 void
68 usage(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
94 extern int forward_flags;
95 static 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>
102 static void
103 krb5_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)
139 extern char *dest_realm, dst_realm_buf[];
140 extern int dst_realm_sz;
141 #endif
142 
143 int
144 main(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