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