xref: /dragonfly/usr.bin/telnet/main.c (revision 9ddb8543)
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  * @(#)main.c	8.3 (Berkeley) 5/30/95
34  * $FreeBSD: src/crypto/telnet/telnet/main.c,v 1.4.2.5 2002/04/13 10:59:08 markm Exp $
35  * $DragonFly: src/crypto/telnet/telnet/main.c,v 1.2 2003/06/17 04:24:37 dillon Exp $
36  */
37 
38 #include <sys/types.h>
39 #include <sys/socket.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <unistd.h>
43 
44 #include "ring.h"
45 #include "externs.h"
46 #include "defines.h"
47 
48 #ifdef	AUTHENTICATION
49 #include <libtelnet/auth.h>
50 #endif
51 #ifdef	ENCRYPTION
52 #include <libtelnet/encrypt.h>
53 #endif
54 
55 /* These values need to be the same as defined in libtelnet/kerberos5.c */
56 /* Either define them in both places, or put in some common header file. */
57 #define OPTS_FORWARD_CREDS	0x00000002
58 #define OPTS_FORWARDABLE_CREDS	0x00000001
59 
60 #if 0
61 #define FORWARD
62 #endif
63 
64 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
65 char *ipsec_policy_in = NULL;
66 char *ipsec_policy_out = NULL;
67 #endif
68 
69 int family = AF_UNSPEC;
70 
71 /*
72  * Initialize variables.
73  */
74 void
75 tninit(void)
76 {
77     init_terminal();
78 
79     init_network();
80 
81     init_telnet();
82 
83     init_sys();
84 }
85 
86 static void
87 usage(void)
88 {
89 	fprintf(stderr, "Usage: %s %s%s%s%s\n",
90 	    prompt,
91 #ifdef	AUTHENTICATION
92 	    "[-4] [-6] [-8] [-E] [-K] [-L] [-N] [-S tos] [-X atype] [-c] [-d]",
93 	    "\n\t[-e char] [-k realm] [-l user] [-f/-F] [-n tracefile] ",
94 #else
95 	    "[-4] [-6] [-8] [-E] [-L] [-N] [-S tos] [-c] [-d]",
96 	    "\n\t[-e char] [-l user] [-n tracefile] ",
97 #endif
98 	    "[-r] [-s src_addr] [-u] ",
99 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
100 	    "[-P policy] "
101 #endif
102 #ifdef	ENCRYPTION
103 	    "[-y] [host-name [port]]"
104 #else	/* ENCRYPTION */
105 	    "[host-name [port]]"
106 #endif	/* ENCRYPTION */
107 	);
108 	exit(1);
109 }
110 
111 /*
112  * main.  Parse arguments, invoke the protocol or command parser.
113  */
114 
115 int
116 main(int argc, char *argv[])
117 {
118 	int ch;
119 	char *user;
120 	char *src_addr = NULL;
121 #ifdef	FORWARD
122 	extern int forward_flags;
123 #endif	/* FORWARD */
124 
125 	tninit();		/* Clear out things */
126 
127 	TerminalSaveState();
128 
129 	if ((prompt = strrchr(argv[0], '/')))
130 		++prompt;
131 	else
132 		prompt = argv[0];
133 
134 	user = NULL;
135 
136 	rlogin = (strncmp(prompt, "rlog", 4) == 0) ? '~' : _POSIX_VDISABLE;
137 #ifdef AUTHENTICATION
138 	autologin = 0;
139 #else
140 	autologin = -1;
141 #endif
142 
143 #ifdef	ENCRYPTION
144 	encrypt_auto(1);
145 	decrypt_auto(1);
146 #endif
147 
148 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
149 #define IPSECOPT	"P:"
150 #else
151 #define IPSECOPT
152 #endif
153 	while ((ch = getopt(argc, argv,
154 			    "468EKLNS:X:acde:fFk:l:n:rs:t:uxy" IPSECOPT)) != -1)
155 #undef IPSECOPT
156 	{
157 		switch(ch) {
158 		case '4':
159 			family = AF_INET;
160 			break;
161 #ifdef INET6
162 		case '6':
163 			family = AF_INET6;
164 			break;
165 #endif
166 		case '8':
167 			eight = 3;	/* binary output and input */
168 			break;
169 		case 'E':
170 			rlogin = escape = _POSIX_VDISABLE;
171 			break;
172 		case 'K':
173 #ifdef	AUTHENTICATION
174 			/* It's the default now, so ignore */
175 #endif
176 			break;
177 		case 'L':
178 			eight |= 2;	/* binary output only */
179 			break;
180 		case 'N':
181 			doaddrlookup = 0;
182 			break;
183 		case 'S':
184 		    {
185 #ifdef	HAS_GETTOS
186 			extern int tos;
187 
188 			if ((tos = parsetos(optarg, "tcp")) < 0)
189 				fprintf(stderr, "%s%s%s%s\n",
190 					prompt, ": Bad TOS argument '",
191 					optarg,
192 					"; will try to use default TOS");
193 #else
194 			fprintf(stderr,
195 			   "%s: Warning: -S ignored, no parsetos() support.\n",
196 								prompt);
197 #endif
198 		    }
199 			break;
200 		case 'X':
201 #ifdef	AUTHENTICATION
202 			auth_disable_name(optarg);
203 #endif
204 			break;
205 		case 'a':
206 			autologin = 1;
207 			break;
208 		case 'c':
209 			skiprc = 1;
210 			break;
211 		case 'd':
212 			debug = 1;
213 			break;
214 		case 'e':
215 			set_escape_char(optarg);
216 			break;
217 		case 'f':
218 #ifdef	AUTHENTICATION
219 #if defined(KRB5) && defined(FORWARD)
220 			if (forward_flags & OPTS_FORWARD_CREDS) {
221 			    fprintf(stderr,
222 				    "%s: Only one of -f and -F allowed.\n",
223 				    prompt);
224 			    usage();
225 			}
226 			forward_flags |= OPTS_FORWARD_CREDS;
227 #else
228 			fprintf(stderr,
229 			 "%s: Warning: -f ignored, no Kerberos V5 support.\n",
230 				prompt);
231 #endif
232 #else
233 			fprintf(stderr,
234 			 "%s: Warning: -f ignored, no Kerberos V5 support.\n",
235 				prompt);
236 #endif
237 			break;
238 		case 'F':
239 #ifdef	AUTHENTICATION
240 #if defined(KRB5) && defined(FORWARD)
241 			if (forward_flags & OPTS_FORWARD_CREDS) {
242 			    fprintf(stderr,
243 				    "%s: Only one of -f and -F allowed.\n",
244 				    prompt);
245 			    usage();
246 			}
247 			forward_flags |= OPTS_FORWARD_CREDS;
248 			forward_flags |= OPTS_FORWARDABLE_CREDS;
249 #else
250 			fprintf(stderr,
251 			 "%s: Warning: -F ignored, no Kerberos V5 support.\n",
252 				prompt);
253 #endif
254 #else
255 			fprintf(stderr,
256 			 "%s: Warning: -F ignored, no Kerberos V5 support.\n",
257 				prompt);
258 #endif
259 			break;
260 		case 'k':
261 #ifdef	AUTHENTICATION
262 #if defined(KRB4)
263 		    {
264 			extern char *dest_realm, dst_realm_buf[], dst_realm_sz;
265 			dest_realm = dst_realm_buf;
266 			(void)strncpy(dest_realm, optarg, dst_realm_sz);
267 		    }
268 #else
269 			fprintf(stderr,
270 			   "%s: Warning: -k ignored, no Kerberos V4 support.\n",
271 								prompt);
272 #endif
273 #else
274 			fprintf(stderr,
275 			   "%s: Warning: -k ignored, no Kerberos V4 support.\n",
276 								prompt);
277 #endif
278 			break;
279 		case 'l':
280 #ifdef	AUTHENTICATION
281 			/* This is the default now, so ignore it */
282 #else
283 			autologin = 1;
284 #endif
285 			user = optarg;
286 			break;
287 		case 'n':
288 				SetNetTrace(optarg);
289 			break;
290 		case 'r':
291 			rlogin = '~';
292 			break;
293 		case 's':
294 			src_addr = optarg;
295 			break;
296 		case 'u':
297 			family = AF_UNIX;
298 			break;
299 		case 'x':
300 #ifndef	ENCRYPTION
301 			fprintf(stderr,
302 			    "%s: Warning: -x ignored, no ENCRYPT support.\n",
303 								prompt);
304 #endif	/* ENCRYPTION */
305 			break;
306 		case 'y':
307 #ifdef	ENCRYPTION
308 			encrypt_auto(0);
309 			decrypt_auto(0);
310 #else
311 			fprintf(stderr,
312 			    "%s: Warning: -y ignored, no ENCRYPT support.\n",
313 								prompt);
314 #endif	/* ENCRYPTION */
315 			break;
316 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
317 		case 'P':
318 			if (!strncmp("in", optarg, 2))
319 				ipsec_policy_in = strdup(optarg);
320 			else if (!strncmp("out", optarg, 3))
321 				ipsec_policy_out = strdup(optarg);
322 			else
323 				usage();
324 			break;
325 #endif
326 		case '?':
327 		default:
328 			usage();
329 			/* NOTREACHED */
330 		}
331 	}
332 	if (autologin == -1)
333 		autologin = (rlogin == _POSIX_VDISABLE) ? 0 : 1;
334 
335 	argc -= optind;
336 	argv += optind;
337 
338 	if (argc) {
339 		char *args[9], **argp = args;
340 
341 		if (argc > 2)
342 			usage();
343 		*argp++ = prompt;
344 		if (user) {
345 			*argp++ = strdup("-l");
346 			*argp++ = user;
347 		}
348 		if (src_addr) {
349 			*argp++ = strdup("-s");
350 			*argp++ = src_addr;
351 		}
352 		*argp++ = argv[0];		/* host */
353 		if (argc > 1)
354 			*argp++ = argv[1];	/* port */
355 		*argp = 0;
356 
357 		if (setjmp(toplevel) != 0)
358 			Exit(0);
359 		if (tn(argp - args, args) == 1)
360 			return (0);
361 		else
362 			return (1);
363 	}
364 	(void)setjmp(toplevel);
365 	for (;;) {
366 			command(1, 0, 0);
367 	}
368 	return 0;
369 }
370