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