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