xref: /netbsd-src/usr.bin/telnet/main.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /*	$NetBSD: main.c,v 1.30 2016/09/05 00:40:30 sevan Exp $	*/
2 
3 /*
4  * Copyright (c) 1988, 1990, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the University nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 
32 #include <sys/cdefs.h>
33 #ifndef lint
34 __COPYRIGHT("@(#) Copyright (c) 1988, 1990, 1993\
35  The Regents of the University of California.  All rights reserved.");
36 #endif /* not lint */
37 
38 #ifndef lint
39 #if 0
40 static char sccsid[] = "@(#)main.c	8.3 (Berkeley) 5/30/95";
41 #else
42 __RCSID("$NetBSD: main.c,v 1.30 2016/09/05 00:40:30 sevan Exp $");
43 #endif
44 #endif /* not lint */
45 
46 #include <sys/types.h>
47 #include <sys/socket.h>
48 
49 #include <unistd.h>
50 
51 #include "ring.h"
52 #include "externs.h"
53 #include "defines.h"
54 #ifdef AUTHENTICATION
55 #include <libtelnet/auth.h>
56 #endif
57 #ifdef ENCRYPTION
58 #include <libtelnet/encrypt.h>
59 #endif
60 
61 /* These values need to be the same as defined in libtelnet/kerberos5.c */
62 /* Either define them in both places, or put in some common header file. */
63 #define OPTS_FORWARD_CREDS	0x00000002
64 #define OPTS_FORWARDABLE_CREDS	0x00000001
65 
66 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
67 char *ipsec_policy_in = NULL;
68 char *ipsec_policy_out = NULL;
69 #endif
70 
71 int family = AF_UNSPEC;
72 
73 /*
74  * Initialize variables.
75  */
76 void
77 tninit(void)
78 {
79     init_terminal();
80 
81     init_network();
82 
83     init_telnet();
84 
85     init_sys();
86 
87 #ifdef TN3270
88     init_3270();
89 #endif
90 }
91 
92 	void
93 usage(void)
94 {
95 	fprintf(stderr, "usage: %s %s%s%s%s\n",
96 	    prompt,
97 #ifdef	AUTHENTICATION
98 	    "[-4] [-6] [-8] [-E] [-K] [-L] [-N] [-S tos] [-X atype] [-a] [-c]",
99 	    "\n\t[-d] [-e char] [-k realm] [-l user] [-f/-F] [-n tracefile] ",
100 #else
101 	    "[-4] [-6] [-8] [-E] [-L] [-N] [-S tos] [-a] [-c] [-d] [-e char]",
102 	    "\n\t[-l user] [-n tracefile] ",
103 #endif
104 #ifdef TN3270
105 # ifdef AUTHENTICATION
106 	    "[-noasynch] [-noasynctty]\n\t[-noasyncnet] [-r] [-t transcom] ",
107 # else
108 	    "[-noasynch] [-noasynctty] [-noasyncnet] [-r]\n\t[-t transcom]",
109 # endif
110 #else
111 	    "[-r] ",
112 #endif
113 #ifdef	ENCRYPTION
114 	    "[-x] "
115 #endif
116 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
117 	    "\n\t[-P policy] [host-name [port]]"
118 #else
119 	    "\n\t[host-name [port]]"
120 #endif
121 	);
122 	exit(1);
123 }
124 
125 /*
126  * main.  Parse arguments, invoke the protocol or command parser.
127  */
128 
129 
130 int
131 main(int argc, char *argv[])
132 {
133 	extern char *optarg;
134 	extern int optind;
135 	int ch;
136 	char *user;
137 #ifdef	FORWARD
138 	extern int forward_flags;
139 #endif	/* FORWARD */
140 
141 	tninit();		/* Clear out things */
142 
143 	TerminalSaveState();
144 
145 	if ((prompt = strrchr(argv[0], '/')) != NULL)
146 		++prompt;
147 	else
148 		prompt = argv[0];
149 
150 	user = NULL;
151 
152 	rlogin = (strncmp(prompt, "rlog", 4) == 0) ? '~' : _POSIX_VDISABLE;
153 	autologin = -1;
154 
155 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
156 #define IPSECOPT	"P:"
157 #else
158 #define IPSECOPT
159 #endif
160 	while ((ch = getopt(argc, argv, "468EKLNS:X:acde:fFk:l:n:rt:x"
161 			IPSECOPT)) != -1) {
162 #undef IPSECOPT
163 		switch(ch) {
164 		case '4':
165 			family = AF_INET;
166 			break;
167 		case '6':
168 			family = AF_INET6;
169 			break;
170 		case '8':
171 			eight = 3;	/* binary output and input */
172 			break;
173 		case 'E':
174 			rlogin = escape = _POSIX_VDISABLE;
175 			break;
176 		case 'K':
177 #ifdef	AUTHENTICATION
178 			autologin = 0;
179 #endif
180 			break;
181 		case 'L':
182 			eight |= 2;	/* binary output only */
183 			break;
184 		case 'N':
185 			doaddrlookup = 0;
186 			break;
187 		case 'S':
188 		    {
189 			fprintf(stderr,
190 			   "%s: Warning: -S ignored, no parsetos() support.\n",
191 								prompt);
192 		    }
193 			break;
194 		case 'X':
195 #ifdef	AUTHENTICATION
196 			auth_disable_name(optarg);
197 #endif
198 			break;
199 		case 'a':
200 			autologin = 1;
201 			break;
202 		case 'c':
203 			skiprc = 1;
204 			break;
205 		case 'd':
206 			telnet_debug = 1;
207 			break;
208 		case 'e':
209 			set_escape_char(optarg);
210 			break;
211 		case 'f':
212 #if defined(AUTHENTICATION) && defined(KRB5) && defined(FORWARD)
213 			if (forward_flags & OPTS_FORWARD_CREDS) {
214 			    fprintf(stderr,
215 				    "%s: Only one of -f and -F allowed.\n",
216 				    prompt);
217 			    usage();
218 			}
219 			forward_flags |= OPTS_FORWARD_CREDS;
220 #else
221 			fprintf(stderr,
222 			 "%s: Warning: -f ignored, no Kerberos V5 support.\n",
223 				prompt);
224 #endif
225 			break;
226 		case 'F':
227 #if defined(AUTHENTICATION) && defined(KRB5) && defined(FORWARD)
228 			if (forward_flags & OPTS_FORWARD_CREDS) {
229 			    fprintf(stderr,
230 				    "%s: Only one of -f and -F allowed.\n",
231 				    prompt);
232 			    usage();
233 			}
234 			forward_flags |= OPTS_FORWARD_CREDS;
235 			forward_flags |= OPTS_FORWARDABLE_CREDS;
236 #else
237 			fprintf(stderr,
238 			 "%s: Warning: -F ignored, no Kerberos V5 support.\n",
239 				prompt);
240 #endif
241 			break;
242 		case 'k':
243 			fprintf(stderr,
244 			   "%s: Warning: -k ignored, no Kerberos V4 support.\n",
245 								prompt);
246 			break;
247 		case 'l':
248 			if(autologin == 0) {
249 				autologin = -1;
250 			}
251 			user = optarg;
252 			break;
253 		case 'n':
254 #ifdef TN3270
255 			/* distinguish between "-n oasynch" and "-noasynch" */
256 			if (argv[optind - 1][0] == '-' && argv[optind - 1][1]
257 			    == 'n' && argv[optind - 1][2] == 'o') {
258 				if (!strcmp(optarg, "oasynch")) {
259 					noasynchtty = 1;
260 					noasynchnet = 1;
261 				} else if (!strcmp(optarg, "oasynchtty"))
262 					noasynchtty = 1;
263 				else if (!strcmp(optarg, "oasynchnet"))
264 					noasynchnet = 1;
265 			} else
266 #endif	/* defined(TN3270) */
267 				SetNetTrace(optarg);
268 			break;
269 		case 'r':
270 			rlogin = '~';
271 			break;
272 		case 't':
273 #ifdef TN3270
274 			(void)strlcpy(tline, optarg, sizeof(tline));
275 			transcom = tline;
276 #else
277 			fprintf(stderr,
278 			   "%s: Warning: -t ignored, no TN3270 support.\n",
279 								prompt);
280 #endif
281 			break;
282 		case 'x':
283 #ifdef	ENCRYPTION
284 			encrypt_auto(1);
285 			decrypt_auto(1);
286 #else	/* ENCRYPTION */
287 			fprintf(stderr,
288 			    "%s: Warning: -x ignored, no ENCRYPT support.\n",
289 								prompt);
290 #endif	/* ENCRYPTION */
291 			break;
292 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
293 		case 'P':
294 			if (!strncmp("in", optarg, 2))
295 				ipsec_policy_in = strdup(optarg);
296 			else if (!strncmp("out", optarg, 3))
297 				ipsec_policy_out = strdup(optarg);
298 			else
299 				usage();
300 			break;
301 #endif
302 		case '?':
303 		default:
304 			usage();
305 			/* NOTREACHED */
306 		}
307 	}
308 
309 	if (autologin == -1) {		/* esc@magic.fi; force  */
310 #if defined(AUTHENTICATION)
311 		autologin = 1;
312 #endif
313 #if defined(ENCRYPTION)
314 		encrypt_auto(1);
315 		decrypt_auto(1);
316 #endif
317 	}
318 
319 	if (autologin == -1)
320 		autologin = (rlogin == _POSIX_VDISABLE) ? 0 : 1;
321 
322 	argc -= optind;
323 	argv += optind;
324 
325 	if (argc) {
326 		static char ml[] = "-l";
327 		char *args[7];
328 		char ** volatile argp;	/* avoid longjmp clobbering */
329 
330 		argp = args;
331 		if (argc > 2)
332 			usage();
333 		*argp++ = prompt;
334 		if (user) {
335 			*argp++ = ml;
336 			*argp++ = user;
337 		}
338 		*argp++ = argv[0];		/* host */
339 		if (argc > 1)
340 			*argp++ = argv[1];	/* port */
341 		*argp = 0;
342 
343 		if (setjmp(toplevel) != 0)
344 			Exit(0);
345 		if (tn(argp - args, args) == 1)
346 			return (0);
347 		else
348 			return (1);
349 	}
350 	(void)setjmp(toplevel);
351 	for (;;) {
352 #ifdef TN3270
353 		if (shell_active)
354 			shell_continue();
355 		else
356 #endif
357 			command(1, 0, 0);
358 	}
359 }
360