xref: /dragonfly/usr.bin/telnet/main.c (revision 8bf5b238)
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. Neither the name of the University nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * @(#)main.c	8.3 (Berkeley) 5/30/95
30  * $FreeBSD: src/crypto/telnet/telnet/main.c,v 1.4.2.5 2002/04/13 10:59:08 markm Exp $
31  */
32 
33 #include <sys/types.h>
34 #include <sys/socket.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <unistd.h>
38 
39 #include "ring.h"
40 #include "externs.h"
41 #include "defines.h"
42 
43 #ifdef	AUTHENTICATION
44 #include <libtelnet/auth.h>
45 #endif
46 #ifdef	ENCRYPTION
47 #include <libtelnet/encrypt.h>
48 #endif
49 
50 /* These values need to be the same as defined in libtelnet/kerberos5.c */
51 /* Either define them in both places, or put in some common header file. */
52 #define OPTS_FORWARD_CREDS	0x00000002
53 #define OPTS_FORWARDABLE_CREDS	0x00000001
54 
55 #if 0
56 #define FORWARD
57 #endif
58 
59 int family = AF_UNSPEC;
60 
61 /*
62  * Initialize variables.
63  */
64 void
65 tninit(void)
66 {
67     init_terminal();
68 
69     init_network();
70 
71     init_telnet();
72 
73     init_sys();
74 }
75 
76 static void
77 usage(void)
78 {
79 	fprintf(stderr, "Usage: %s %s%s%s%s\n",
80 	    prompt,
81 #ifdef	AUTHENTICATION
82 	    "[-4] [-6] [-8] [-E] [-K] [-L] [-N] [-S tos] [-X atype] [-c] [-d]",
83 	    "\n\t[-e char] [-k realm] [-l user] [-f/-F] [-n tracefile] ",
84 #else
85 	    "[-4] [-6] [-8] [-E] [-L] [-N] [-S tos] [-c] [-d]",
86 	    "\n\t[-e char] [-l user] [-n tracefile] ",
87 #endif
88 	    "[-r] [-s src_addr] [-u] ",
89 #ifdef	ENCRYPTION
90 	    "[-y] [host-name [port]]"
91 #else	/* ENCRYPTION */
92 	    "[host-name [port]]"
93 #endif	/* ENCRYPTION */
94 	);
95 	exit(1);
96 }
97 
98 /*
99  * main.  Parse arguments, invoke the protocol or command parser.
100  */
101 
102 int
103 main(int argc, char *argv[])
104 {
105 	int ch;
106 	char *user;
107 	char *src_addr = NULL;
108 #ifdef	FORWARD
109 	extern int forward_flags;
110 #endif	/* FORWARD */
111 
112 	tninit();		/* Clear out things */
113 
114 	TerminalSaveState();
115 
116 	if ((prompt = strrchr(argv[0], '/')))
117 		++prompt;
118 	else
119 		prompt = argv[0];
120 
121 	user = NULL;
122 
123 	rlogin = (strncmp(prompt, "rlog", 4) == 0) ? '~' : _POSIX_VDISABLE;
124 #ifdef AUTHENTICATION
125 	autologin = 0;
126 #else
127 	autologin = -1;
128 #endif
129 
130 #ifdef	ENCRYPTION
131 	encrypt_auto(1);
132 	decrypt_auto(1);
133 #endif
134 
135 	while ((ch = getopt(argc, argv, "468EKLNS:X:acde:fFk:l:n:rs:t:uxy")) != -1) {
136 		switch(ch) {
137 		case '4':
138 			family = AF_INET;
139 			break;
140 #ifdef INET6
141 		case '6':
142 			family = AF_INET6;
143 			break;
144 #endif
145 		case '8':
146 			eight = 3;	/* binary output and input */
147 			break;
148 		case 'E':
149 			rlogin = escape = _POSIX_VDISABLE;
150 			break;
151 		case 'K':
152 #ifdef	AUTHENTICATION
153 			/* It's the default now, so ignore */
154 #endif
155 			break;
156 		case 'L':
157 			eight |= 2;	/* binary output only */
158 			break;
159 		case 'N':
160 			doaddrlookup = 0;
161 			break;
162 		case 'S':
163 		    {
164 #ifdef	HAS_GETTOS
165 			extern int tos;
166 
167 			if ((tos = parsetos(optarg, "tcp")) < 0)
168 				fprintf(stderr, "%s%s%s%s\n",
169 					prompt, ": Bad TOS argument '",
170 					optarg,
171 					"; will try to use default TOS");
172 #else
173 			fprintf(stderr,
174 			   "%s: Warning: -S ignored, no parsetos() support.\n",
175 								prompt);
176 #endif
177 		    }
178 			break;
179 		case 'X':
180 #ifdef	AUTHENTICATION
181 			auth_disable_name(optarg);
182 #endif
183 			break;
184 		case 'a':
185 			autologin = 1;
186 			break;
187 		case 'c':
188 			skiprc = 1;
189 			break;
190 		case 'd':
191 			telnet_debug = 1;
192 			break;
193 		case 'e':
194 			set_escape_char(optarg);
195 			break;
196 		case 'f':
197 #ifdef	AUTHENTICATION
198 #if defined(KRB5) && defined(FORWARD)
199 			if (forward_flags & OPTS_FORWARD_CREDS) {
200 			    fprintf(stderr,
201 				    "%s: Only one of -f and -F allowed.\n",
202 				    prompt);
203 			    usage();
204 			}
205 			forward_flags |= OPTS_FORWARD_CREDS;
206 #else
207 			fprintf(stderr,
208 			 "%s: Warning: -f ignored, no Kerberos V5 support.\n",
209 				prompt);
210 #endif
211 #else
212 			fprintf(stderr,
213 			 "%s: Warning: -f ignored, no Kerberos V5 support.\n",
214 				prompt);
215 #endif
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 			forward_flags |= OPTS_FORWARDABLE_CREDS;
228 #else
229 			fprintf(stderr,
230 			 "%s: Warning: -F ignored, no Kerberos V5 support.\n",
231 				prompt);
232 #endif
233 #else
234 			fprintf(stderr,
235 			 "%s: Warning: -F ignored, no Kerberos V5 support.\n",
236 				prompt);
237 #endif
238 			break;
239 		case 'k':
240 #ifdef	AUTHENTICATION
241 #if defined(KRB4)
242 		    {
243 			extern char *dest_realm, dst_realm_buf[], dst_realm_sz;
244 			dest_realm = dst_realm_buf;
245 			(void)strncpy(dest_realm, optarg, dst_realm_sz);
246 		    }
247 #else
248 			fprintf(stderr,
249 			   "%s: Warning: -k ignored, no Kerberos V4 support.\n",
250 								prompt);
251 #endif
252 #else
253 			fprintf(stderr,
254 			   "%s: Warning: -k ignored, no Kerberos V4 support.\n",
255 								prompt);
256 #endif
257 			break;
258 		case 'l':
259 #ifdef	AUTHENTICATION
260 			/* This is the default now, so ignore it */
261 #else
262 			autologin = 1;
263 #endif
264 			user = optarg;
265 			break;
266 		case 'n':
267 				SetNetTrace(optarg);
268 			break;
269 		case 'r':
270 			rlogin = '~';
271 			break;
272 		case 's':
273 			src_addr = optarg;
274 			break;
275 		case 'u':
276 			family = AF_UNIX;
277 			break;
278 		case 'x':
279 #ifndef	ENCRYPTION
280 			fprintf(stderr,
281 			    "%s: Warning: -x ignored, no ENCRYPT support.\n",
282 								prompt);
283 #endif	/* ENCRYPTION */
284 			break;
285 		case 'y':
286 #ifdef	ENCRYPTION
287 			encrypt_auto(0);
288 			decrypt_auto(0);
289 #else
290 			fprintf(stderr,
291 			    "%s: Warning: -y ignored, no ENCRYPT support.\n",
292 								prompt);
293 #endif	/* ENCRYPTION */
294 			break;
295 		case '?':
296 		default:
297 			usage();
298 			/* NOTREACHED */
299 		}
300 	}
301 	if (autologin == -1)
302 		autologin = (rlogin == _POSIX_VDISABLE) ? 0 : 1;
303 
304 	argc -= optind;
305 	argv += optind;
306 
307 	if (argc) {
308 		char *args[9], **argp = args;
309 
310 		if (argc > 2)
311 			usage();
312 		*argp++ = prompt;
313 		if (user) {
314 			*argp++ = strdup("-l");
315 			*argp++ = user;
316 		}
317 		if (src_addr) {
318 			*argp++ = strdup("-s");
319 			*argp++ = src_addr;
320 		}
321 		*argp++ = argv[0];		/* host */
322 		if (argc > 1)
323 			*argp++ = argv[1];	/* port */
324 		*argp = NULL;
325 
326 		if (setjmp(toplevel) != 0)
327 			Exit(0);
328 		if (tn(argp - args, args) == 1)
329 			return (0);
330 		else
331 			return (1);
332 	}
333 	(void)setjmp(toplevel);
334 	for (;;) {
335 			command(1, 0, 0);
336 	}
337 	return 0;
338 }
339