1 /*- 2 * Copyright (c) 1991, 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 * $FreeBSD$ 34 */ 35 36 #ifndef lint 37 static const char sccsid[] = "@(#)auth.c 8.3 (Berkeley) 5/30/95"; 38 #endif /* not lint */ 39 40 /* 41 * Copyright (C) 1990 by the Massachusetts Institute of Technology 42 * 43 * Export of this software from the United States of America is assumed 44 * to require a specific license from the United States Government. 45 * It is the responsibility of any person or organization contemplating 46 * export to obtain such a license before exporting. 47 * 48 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 49 * distribute this software and its documentation for any purpose and 50 * without fee is hereby granted, provided that the above copyright 51 * notice appear in all copies and that both that copyright notice and 52 * this permission notice appear in supporting documentation, and that 53 * the name of M.I.T. not be used in advertising or publicity pertaining 54 * to distribution of the software without specific, written prior 55 * permission. M.I.T. makes no representations about the suitability of 56 * this software for any purpose. It is provided "as is" without express 57 * or implied warranty. 58 */ 59 60 61 #if defined(AUTHENTICATION) 62 #include <stdio.h> 63 #include <sys/types.h> 64 #include <signal.h> 65 #define AUTH_NAMES 66 #include <arpa/telnet.h> 67 #ifdef __STDC__ 68 #include <stdlib.h> 69 #include <unistd.h> 70 #endif 71 #ifdef NO_STRING_H 72 #include <strings.h> 73 #else 74 #include <string.h> 75 #endif 76 77 #include "encrypt.h" 78 #include "auth.h" 79 #include "misc-proto.h" 80 #include "auth-proto.h" 81 82 #define typemask(x) (1<<((x)-1)) 83 84 #ifdef KRB4_ENCPWD 85 extern krb4encpwd_init(); 86 extern krb4encpwd_send(); 87 extern krb4encpwd_is(); 88 extern krb4encpwd_reply(); 89 extern krb4encpwd_status(); 90 extern krb4encpwd_printsub(); 91 #endif 92 93 #ifdef RSA_ENCPWD 94 extern rsaencpwd_init(); 95 extern rsaencpwd_send(); 96 extern rsaencpwd_is(); 97 extern rsaencpwd_reply(); 98 extern rsaencpwd_status(); 99 extern rsaencpwd_printsub(); 100 #endif 101 102 int auth_debug_mode = 0; 103 static char *Name = "Noname"; 104 static int Server = 0; 105 static Authenticator *authenticated = 0; 106 static int authenticating = 0; 107 static int validuser = 0; 108 static unsigned char _auth_send_data[256]; 109 static unsigned char *auth_send_data; 110 static int auth_send_cnt = 0; 111 112 int auth_onoff(char *type, int on); 113 void auth_encrypt_user(char *name); 114 115 /* 116 * Authentication types supported. Plese note that these are stored 117 * in priority order, i.e. try the first one first. 118 */ 119 Authenticator authenticators[] = { 120 #ifdef SPX 121 { AUTHTYPE_SPX, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL, 122 spx_init, 123 spx_send, 124 spx_is, 125 spx_reply, 126 spx_status, 127 spx_printsub }, 128 { AUTHTYPE_SPX, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY, 129 spx_init, 130 spx_send, 131 spx_is, 132 spx_reply, 133 spx_status, 134 spx_printsub }, 135 #endif 136 #ifdef KRB5 137 # ifdef ENCRYPTION 138 { AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL, 139 kerberos5_init, 140 kerberos5_send, 141 kerberos5_is, 142 kerberos5_reply, 143 kerberos5_status, 144 kerberos5_printsub }, 145 # endif /* ENCRYPTION */ 146 { AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY, 147 kerberos5_init, 148 kerberos5_send, 149 kerberos5_is, 150 kerberos5_reply, 151 kerberos5_status, 152 kerberos5_printsub }, 153 #endif 154 #ifdef KRB4 155 # ifdef ENCRYPTION 156 { AUTHTYPE_KERBEROS_V4, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL, 157 kerberos4_init, 158 kerberos4_send, 159 kerberos4_is, 160 kerberos4_reply, 161 kerberos4_status, 162 kerberos4_printsub }, 163 # endif /* ENCRYPTION */ 164 { AUTHTYPE_KERBEROS_V4, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY, 165 kerberos4_init, 166 kerberos4_send, 167 kerberos4_is, 168 kerberos4_reply, 169 kerberos4_status, 170 kerberos4_printsub }, 171 #endif 172 #ifdef KRB4_ENCPWD 173 { AUTHTYPE_KRB4_ENCPWD, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL, 174 krb4encpwd_init, 175 krb4encpwd_send, 176 krb4encpwd_is, 177 krb4encpwd_reply, 178 krb4encpwd_status, 179 krb4encpwd_printsub }, 180 #endif 181 #ifdef RSA_ENCPWD 182 { AUTHTYPE_RSA_ENCPWD, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY, 183 rsaencpwd_init, 184 rsaencpwd_send, 185 rsaencpwd_is, 186 rsaencpwd_reply, 187 rsaencpwd_status, 188 rsaencpwd_printsub }, 189 #endif 190 #ifdef SRA 191 { AUTHTYPE_SRA, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY, 192 sra_init, 193 sra_send, 194 sra_is, 195 sra_reply, 196 sra_status, 197 sra_printsub }, 198 199 #endif 200 { 0, }, 201 }; 202 203 static Authenticator NoAuth = { 0 }; 204 205 static int i_support = 0; 206 static int i_wont_support = 0; 207 208 Authenticator * 209 findauthenticator(type, way) 210 int type; 211 int way; 212 { 213 Authenticator *ap = authenticators; 214 215 while (ap->type && (ap->type != type || ap->way != way)) 216 ++ap; 217 return(ap->type ? ap : 0); 218 } 219 220 void 221 auth_init(name, server) 222 char *name; 223 int server; 224 { 225 Authenticator *ap = authenticators; 226 227 Server = server; 228 Name = name; 229 230 i_support = 0; 231 authenticated = 0; 232 authenticating = 0; 233 while (ap->type) { 234 if (!ap->init || (*ap->init)(ap, server)) { 235 i_support |= typemask(ap->type); 236 if (auth_debug_mode) 237 printf(">>>%s: I support auth type %d %d\r\n", 238 Name, 239 ap->type, ap->way); 240 } 241 else if (auth_debug_mode) 242 printf(">>>%s: Init failed: auth type %d %d\r\n", 243 Name, ap->type, ap->way); 244 ++ap; 245 } 246 } 247 248 void 249 auth_disable_name(name) 250 char *name; 251 { 252 int x; 253 for (x = 0; x < AUTHTYPE_CNT; ++x) { 254 if (AUTHTYPE_NAME(x) && !strcasecmp(name, AUTHTYPE_NAME(x))) { 255 i_wont_support |= typemask(x); 256 break; 257 } 258 } 259 } 260 261 int 262 getauthmask(type, maskp) 263 char *type; 264 int *maskp; 265 { 266 register int x; 267 268 if (AUTHTYPE_NAME(0) && !strcasecmp(type, AUTHTYPE_NAME(0))) { 269 *maskp = -1; 270 return(1); 271 } 272 273 for (x = 1; x < AUTHTYPE_CNT; ++x) { 274 if (AUTHTYPE_NAME(x) && !strcasecmp(type, AUTHTYPE_NAME(x))) { 275 *maskp = typemask(x); 276 return(1); 277 } 278 } 279 return(0); 280 } 281 282 int 283 auth_enable(type) 284 char *type; 285 { 286 return(auth_onoff(type, 1)); 287 } 288 289 int 290 auth_disable(type) 291 char *type; 292 { 293 return(auth_onoff(type, 0)); 294 } 295 296 int 297 auth_onoff(type, on) 298 char *type; 299 int on; 300 { 301 int i, mask = -1; 302 Authenticator *ap; 303 304 if (!strcasecmp(type, "?") || !strcasecmp(type, "help")) { 305 printf("auth %s 'type'\n", on ? "enable" : "disable"); 306 printf("Where 'type' is one of:\n"); 307 printf("\t%s\n", AUTHTYPE_NAME(0)); 308 mask = 0; 309 for (ap = authenticators; ap->type; ap++) { 310 if ((mask & (i = typemask(ap->type))) != 0) 311 continue; 312 mask |= i; 313 printf("\t%s\n", AUTHTYPE_NAME(ap->type)); 314 } 315 return(0); 316 } 317 318 if (!getauthmask(type, &mask)) { 319 printf("%s: invalid authentication type\n", type); 320 return(0); 321 } 322 if (on) 323 i_wont_support &= ~mask; 324 else 325 i_wont_support |= mask; 326 return(1); 327 } 328 329 int 330 auth_togdebug(on) 331 int on; 332 { 333 if (on < 0) 334 auth_debug_mode ^= 1; 335 else 336 auth_debug_mode = on; 337 printf("auth debugging %s\n", auth_debug_mode ? "enabled" : "disabled"); 338 return(1); 339 } 340 341 int 342 auth_status() 343 { 344 Authenticator *ap; 345 int i, mask; 346 347 if (i_wont_support == -1) 348 printf("Authentication disabled\n"); 349 else 350 printf("Authentication enabled\n"); 351 352 mask = 0; 353 for (ap = authenticators; ap->type; ap++) { 354 if ((mask & (i = typemask(ap->type))) != 0) 355 continue; 356 mask |= i; 357 printf("%s: %s\n", AUTHTYPE_NAME(ap->type), 358 (i_wont_support & typemask(ap->type)) ? 359 "disabled" : "enabled"); 360 } 361 return(1); 362 } 363 364 /* 365 * This routine is called by the server to start authentication 366 * negotiation. 367 */ 368 void 369 auth_request() 370 { 371 static unsigned char str_request[64] = { IAC, SB, 372 TELOPT_AUTHENTICATION, 373 TELQUAL_SEND, }; 374 Authenticator *ap = authenticators; 375 unsigned char *e = str_request + 4; 376 377 if (!authenticating) { 378 authenticating = 1; 379 while (ap->type) { 380 if (i_support & ~i_wont_support & typemask(ap->type)) { 381 if (auth_debug_mode) { 382 printf(">>>%s: Sending type %d %d\r\n", 383 Name, ap->type, ap->way); 384 } 385 *e++ = ap->type; 386 *e++ = ap->way; 387 } 388 ++ap; 389 } 390 *e++ = IAC; 391 *e++ = SE; 392 net_write(str_request, e - str_request); 393 printsub('>', &str_request[2], e - str_request - 2); 394 } 395 } 396 397 /* 398 * This is called when an AUTH SEND is received. 399 * It should never arrive on the server side (as only the server can 400 * send an AUTH SEND). 401 * You should probably respond to it if you can... 402 * 403 * If you want to respond to the types out of order (i.e. even 404 * if he sends LOGIN KERBEROS and you support both, you respond 405 * with KERBEROS instead of LOGIN (which is against what the 406 * protocol says)) you will have to hack this code... 407 */ 408 void 409 auth_send(data, cnt) 410 unsigned char *data; 411 int cnt; 412 { 413 Authenticator *ap; 414 static unsigned char str_none[] = { IAC, SB, TELOPT_AUTHENTICATION, 415 TELQUAL_IS, AUTHTYPE_NULL, 0, 416 IAC, SE }; 417 if (Server) { 418 if (auth_debug_mode) { 419 printf(">>>%s: auth_send called!\r\n", Name); 420 } 421 return; 422 } 423 424 if (auth_debug_mode) { 425 printf(">>>%s: auth_send got:", Name); 426 printd(data, cnt); printf("\r\n"); 427 } 428 429 /* 430 * Save the data, if it is new, so that we can continue looking 431 * at it if the authorization we try doesn't work 432 */ 433 if (data < _auth_send_data || 434 data > _auth_send_data + sizeof(_auth_send_data)) { 435 auth_send_cnt = cnt > sizeof(_auth_send_data) 436 ? sizeof(_auth_send_data) 437 : cnt; 438 memmove((void *)_auth_send_data, (void *)data, auth_send_cnt); 439 auth_send_data = _auth_send_data; 440 } else { 441 /* 442 * This is probably a no-op, but we just make sure 443 */ 444 auth_send_data = data; 445 auth_send_cnt = cnt; 446 } 447 while ((auth_send_cnt -= 2) >= 0) { 448 if (auth_debug_mode) 449 printf(">>>%s: He supports %d\r\n", 450 Name, *auth_send_data); 451 if ((i_support & ~i_wont_support) & typemask(*auth_send_data)) { 452 ap = findauthenticator(auth_send_data[0], 453 auth_send_data[1]); 454 if (ap && ap->send) { 455 if (auth_debug_mode) 456 printf(">>>%s: Trying %d %d\r\n", 457 Name, auth_send_data[0], 458 auth_send_data[1]); 459 if ((*ap->send)(ap)) { 460 /* 461 * Okay, we found one we like 462 * and did it. 463 * we can go home now. 464 */ 465 if (auth_debug_mode) 466 printf(">>>%s: Using type %d\r\n", 467 Name, *auth_send_data); 468 auth_send_data += 2; 469 return; 470 } 471 } 472 /* else 473 * just continue on and look for the 474 * next one if we didn't do anything. 475 */ 476 } 477 auth_send_data += 2; 478 } 479 net_write(str_none, sizeof(str_none)); 480 printsub('>', &str_none[2], sizeof(str_none) - 2); 481 if (auth_debug_mode) 482 printf(">>>%s: Sent failure message\r\n", Name); 483 auth_finished(0, AUTH_REJECT); 484 #ifdef KANNAN 485 /* 486 * We requested strong authentication, however no mechanisms worked. 487 * Therefore, exit on client end. 488 */ 489 printf("Unable to securely authenticate user ... exit\n"); 490 exit(0); 491 #endif /* KANNAN */ 492 } 493 494 void 495 auth_send_retry() 496 { 497 /* 498 * if auth_send_cnt <= 0 then auth_send will end up rejecting 499 * the authentication and informing the other side of this. 500 */ 501 auth_send(auth_send_data, auth_send_cnt); 502 } 503 504 void 505 auth_is(data, cnt) 506 unsigned char *data; 507 int cnt; 508 { 509 Authenticator *ap; 510 511 if (cnt < 2) 512 return; 513 514 if (data[0] == AUTHTYPE_NULL) { 515 auth_finished(0, AUTH_REJECT); 516 return; 517 } 518 519 if ((ap = findauthenticator(data[0], data[1]))) { 520 if (ap->is) 521 (*ap->is)(ap, data+2, cnt-2); 522 } else if (auth_debug_mode) 523 printf(">>>%s: Invalid authentication in IS: %d\r\n", 524 Name, *data); 525 } 526 527 void 528 auth_reply(data, cnt) 529 unsigned char *data; 530 int cnt; 531 { 532 Authenticator *ap; 533 534 if (cnt < 2) 535 return; 536 537 if ((ap = findauthenticator(data[0], data[1]))) { 538 if (ap->reply) 539 (*ap->reply)(ap, data+2, cnt-2); 540 } else if (auth_debug_mode) 541 printf(">>>%s: Invalid authentication in SEND: %d\r\n", 542 Name, *data); 543 } 544 545 void 546 auth_name(data, cnt) 547 unsigned char *data; 548 int cnt; 549 { 550 unsigned char savename[256]; 551 552 if (cnt < 1) { 553 if (auth_debug_mode) 554 printf(">>>%s: Empty name in NAME\r\n", Name); 555 return; 556 } 557 if (cnt > sizeof(savename) - 1) { 558 if (auth_debug_mode) 559 printf(">>>%s: Name in NAME (%d) exceeds %d length\r\n", 560 Name, cnt, sizeof(savename)-1); 561 return; 562 } 563 memmove((void *)savename, (void *)data, cnt); 564 savename[cnt] = '\0'; /* Null terminate */ 565 if (auth_debug_mode) 566 printf(">>>%s: Got NAME [%s]\r\n", Name, savename); 567 auth_encrypt_user(savename); 568 } 569 570 int 571 auth_sendname(cp, len) 572 unsigned char *cp; 573 int len; 574 { 575 static unsigned char str_request[256+6] 576 = { IAC, SB, TELOPT_AUTHENTICATION, TELQUAL_NAME, }; 577 register unsigned char *e = str_request + 4; 578 register unsigned char *ee = &str_request[sizeof(str_request)-2]; 579 580 while (--len >= 0) { 581 if ((*e++ = *cp++) == IAC) 582 *e++ = IAC; 583 if (e >= ee) 584 return(0); 585 } 586 *e++ = IAC; 587 *e++ = SE; 588 net_write(str_request, e - str_request); 589 printsub('>', &str_request[2], e - &str_request[2]); 590 return(1); 591 } 592 593 void 594 auth_finished(ap, result) 595 Authenticator *ap; 596 int result; 597 { 598 if (!(authenticated = ap)) 599 authenticated = &NoAuth; 600 validuser = result; 601 } 602 603 /* ARGSUSED */ 604 static void 605 auth_intr(sig) 606 int sig; 607 { 608 auth_finished(0, AUTH_REJECT); 609 } 610 611 int 612 auth_wait(name) 613 char *name; 614 { 615 if (auth_debug_mode) 616 printf(">>>%s: in auth_wait.\r\n", Name); 617 618 if (Server && !authenticating) 619 return(0); 620 621 (void) signal(SIGALRM, auth_intr); 622 alarm(30); 623 while (!authenticated) 624 if (telnet_spin()) 625 break; 626 alarm(0); 627 (void) signal(SIGALRM, SIG_DFL); 628 629 /* 630 * Now check to see if the user is valid or not 631 */ 632 if (!authenticated || authenticated == &NoAuth) 633 return(AUTH_REJECT); 634 635 if (validuser == AUTH_VALID) 636 validuser = AUTH_USER; 637 638 if (authenticated->status) 639 validuser = (*authenticated->status)(authenticated, 640 name, validuser); 641 return(validuser); 642 } 643 644 void 645 auth_debug(mode) 646 int mode; 647 { 648 auth_debug_mode = mode; 649 } 650 651 void 652 auth_printsub(data, cnt, buf, buflen) 653 unsigned char *data, *buf; 654 int cnt, buflen; 655 { 656 Authenticator *ap; 657 658 if ((ap = findauthenticator(data[1], data[2])) && ap->printsub) 659 (*ap->printsub)(data, cnt, buf, buflen); 660 else 661 auth_gen_printsub(data, cnt, buf, buflen); 662 } 663 664 void 665 auth_gen_printsub(data, cnt, buf, buflen) 666 unsigned char *data, *buf; 667 int cnt, buflen; 668 { 669 register unsigned char *cp; 670 unsigned char tbuf[16]; 671 672 cnt -= 3; 673 data += 3; 674 buf[buflen-1] = '\0'; 675 buf[buflen-2] = '*'; 676 buflen -= 2; 677 for (; cnt > 0; cnt--, data++) { 678 sprintf((char *)tbuf, " %d", *data); 679 for (cp = tbuf; *cp && buflen > 0; --buflen) 680 *buf++ = *cp++; 681 if (buflen <= 0) 682 return; 683 } 684 *buf = '\0'; 685 } 686 #endif 687