radius.c (96582) | radius.c (96730) |
---|---|
1/* 2 * Copyright 1999 Internet Business Solutions Ltd., Switzerland 3 * 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 unchanged lines hidden (view full) --- 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * | 1/* 2 * Copyright 1999 Internet Business Solutions Ltd., Switzerland 3 * 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 unchanged lines hidden (view full) --- 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * |
26 * $FreeBSD: head/usr.sbin/ppp/radius.c 96582 2002-05-14 12:55:39Z brian $ | 26 * $FreeBSD: head/usr.sbin/ppp/radius.c 96730 2002-05-16 13:34:20Z brian $ |
27 * 28 */ 29 30#include <sys/param.h> 31#include <sys/socket.h> 32#include <netinet/in_systm.h> 33#include <netinet/in.h> 34#include <netinet/ip.h> --- 50 unchanged lines hidden (view full) --- 85#include "cbcp.h" 86#include "chap.h" 87#include "datalink.h" 88#include "ncp.h" 89#include "bundle.h" 90#include "proto.h" 91 92#ifndef NODES | 27 * 28 */ 29 30#include <sys/param.h> 31#include <sys/socket.h> 32#include <netinet/in_systm.h> 33#include <netinet/in.h> 34#include <netinet/ip.h> --- 50 unchanged lines hidden (view full) --- 85#include "cbcp.h" 86#include "chap.h" 87#include "datalink.h" 88#include "ncp.h" 89#include "bundle.h" 90#include "proto.h" 91 92#ifndef NODES |
93struct mschap_request { | 93struct mschap_response { |
94 u_char ident; 95 u_char flags; 96 u_char lm_response[24]; 97 u_char nt_response[24]; 98}; | 94 u_char ident; 95 u_char flags; 96 u_char lm_response[24]; 97 u_char nt_response[24]; 98}; |
99 100struct mschap2_response { 101 u_char ident; 102 u_char flags; 103 u_char pchallenge[16]; 104 u_char reserved[8]; 105 u_char response[24]; 106}; |
|
99#endif 100 101/* 102 * rad_continue_send_request() has given us `got' (non-zero). Deal with it. 103 */ 104static void 105radius_Process(struct radius *r, int got) 106{ --- 195 unchanged lines hidden (view full) --- 302 log_Printf(LogERROR, "rad_cvt_string: %s\n", 303 rad_strerror(r->cx.rad)); 304 auth_Failure(r->cx.auth); 305 rad_close(r->cx.rad); 306 return; 307 } 308 log_Printf(LogPHASE, " MS-CHAP-Error \"%s\"\n", r->errstr); 309 break; | 107#endif 108 109/* 110 * rad_continue_send_request() has given us `got' (non-zero). Deal with it. 111 */ 112static void 113radius_Process(struct radius *r, int got) 114{ --- 195 unchanged lines hidden (view full) --- 310 log_Printf(LogERROR, "rad_cvt_string: %s\n", 311 rad_strerror(r->cx.rad)); 312 auth_Failure(r->cx.auth); 313 rad_close(r->cx.rad); 314 return; 315 } 316 log_Printf(LogPHASE, " MS-CHAP-Error \"%s\"\n", r->errstr); 317 break; |
318 319 case RAD_MICROSOFT_MS_CHAP2_SUCCESS: 320 free(r->msrepstr); 321 if ((r->msrepstr = rad_cvt_string(data, len)) == NULL) { 322 log_Printf(LogERROR, "rad_cvt_string: %s\n", 323 rad_strerror(r->cx.rad)); 324 auth_Failure(r->cx.auth); 325 rad_close(r->cx.rad); 326 return; 327 } 328 log_Printf(LogPHASE, " MS-CHAP2-Success \"%s\"\n", r->msrepstr); 329 break; |
|
310 311 default: 312 log_Printf(LogDEBUG, "Dropping MICROSOFT vendor specific " 313 "RADIUS attribute %d\n", res); 314 break; 315 } 316 break; 317 --- 118 unchanged lines hidden (view full) --- 436 memset(&r->cx.timer, '\0', sizeof r->cx.timer); 437 r->cx.auth = NULL; 438 r->valid = 0; 439 r->vj = 0; 440 r->ip.s_addr = INADDR_ANY; 441 r->mask.s_addr = INADDR_NONE; 442 r->routes = NULL; 443 r->mtu = DEF_MTU; | 330 331 default: 332 log_Printf(LogDEBUG, "Dropping MICROSOFT vendor specific " 333 "RADIUS attribute %d\n", res); 334 break; 335 } 336 break; 337 --- 118 unchanged lines hidden (view full) --- 456 memset(&r->cx.timer, '\0', sizeof r->cx.timer); 457 r->cx.auth = NULL; 458 r->valid = 0; 459 r->vj = 0; 460 r->ip.s_addr = INADDR_ANY; 461 r->mask.s_addr = INADDR_NONE; 462 r->routes = NULL; 463 r->mtu = DEF_MTU; |
464 r->msrepstr = NULL; |
|
444 r->repstr = NULL; 445 r->errstr = NULL; 446 *r->cfg.file = '\0';; 447 log_Printf(LogDEBUG, "Radius: radius_Init\n"); 448} 449 450/* 451 * Forget everything and go back to initialised state. 452 */ 453void 454radius_Destroy(struct radius *r) 455{ 456 r->valid = 0; 457 log_Printf(LogDEBUG, "Radius: radius_Destroy\n"); 458 timer_Stop(&r->cx.timer); 459 route_DeleteAll(&r->routes); 460 free(r->filterid); 461 r->filterid = NULL; | 465 r->repstr = NULL; 466 r->errstr = NULL; 467 *r->cfg.file = '\0';; 468 log_Printf(LogDEBUG, "Radius: radius_Init\n"); 469} 470 471/* 472 * Forget everything and go back to initialised state. 473 */ 474void 475radius_Destroy(struct radius *r) 476{ 477 r->valid = 0; 478 log_Printf(LogDEBUG, "Radius: radius_Destroy\n"); 479 timer_Stop(&r->cx.timer); 480 route_DeleteAll(&r->routes); 481 free(r->filterid); 482 r->filterid = NULL; |
483 free(r->msrepstr); 484 r->msrepstr = NULL; |
|
462 free(r->repstr); 463 r->repstr = NULL; 464 free(r->errstr); 465 r->errstr = NULL; 466 if (r->cx.fd != -1) { 467 r->cx.fd = -1; 468 rad_close(r->cx.rad); 469 } --- 42 unchanged lines hidden (view full) --- 512 } 513 514 return 1; 515} 516 517/* 518 * Start an authentication request to the RADIUS server. 519 */ | 485 free(r->repstr); 486 r->repstr = NULL; 487 free(r->errstr); 488 r->errstr = NULL; 489 if (r->cx.fd != -1) { 490 r->cx.fd = -1; 491 rad_close(r->cx.rad); 492 } --- 42 unchanged lines hidden (view full) --- 535 } 536 537 return 1; 538} 539 540/* 541 * Start an authentication request to the RADIUS server. 542 */ |
520void | 543int |
521radius_Authenticate(struct radius *r, struct authinfo *authp, const char *name, | 544radius_Authenticate(struct radius *r, struct authinfo *authp, const char *name, |
522 const char *key, int klen, const char *challenge, int clen) | 545 const char *key, int klen, const char *nchallenge, 546 int nclen, const char *pchallenge, int pclen) |
523{ 524 struct timeval tv; 525 int got; 526 char hostname[MAXHOSTNAMELEN]; 527 struct hostent *hp; 528 struct in_addr hostaddr; 529#ifndef NODES | 547{ 548 struct timeval tv; 549 int got; 550 char hostname[MAXHOSTNAMELEN]; 551 struct hostent *hp; 552 struct in_addr hostaddr; 553#ifndef NODES |
530 struct mschap_request msreq; | 554 struct mschap_response msresp; 555 struct mschap2_response msresp2; |
531#endif 532 533 if (!*r->cfg.file) | 556#endif 557 558 if (!*r->cfg.file) |
534 return; | 559 return 0; |
535 536 if (r->cx.fd != -1) 537 /* 538 * We assume that our name/key/challenge is the same as last time, 539 * and just continue to wait for the RADIUS server(s). 540 */ | 560 561 if (r->cx.fd != -1) 562 /* 563 * We assume that our name/key/challenge is the same as last time, 564 * and just continue to wait for the RADIUS server(s). 565 */ |
541 return; | 566 return 1; |
542 543 radius_Destroy(r); 544 545 if ((r->cx.rad = rad_auth_open()) == NULL) { 546 log_Printf(LogERROR, "rad_auth_open: %s\n", strerror(errno)); | 567 568 radius_Destroy(r); 569 570 if ((r->cx.rad = rad_auth_open()) == NULL) { 571 log_Printf(LogERROR, "rad_auth_open: %s\n", strerror(errno)); |
547 return; | 572 return 0; |
548 } 549 550 if (rad_config(r->cx.rad, r->cfg.file) != 0) { 551 log_Printf(LogERROR, "rad_config: %s\n", rad_strerror(r->cx.rad)); 552 rad_close(r->cx.rad); | 573 } 574 575 if (rad_config(r->cx.rad, r->cfg.file) != 0) { 576 log_Printf(LogERROR, "rad_config: %s\n", rad_strerror(r->cx.rad)); 577 rad_close(r->cx.rad); |
553 return; | 578 return 0; |
554 } 555 556 if (rad_create_request(r->cx.rad, RAD_ACCESS_REQUEST) != 0) { 557 log_Printf(LogERROR, "rad_create_request: %s\n", rad_strerror(r->cx.rad)); 558 rad_close(r->cx.rad); | 579 } 580 581 if (rad_create_request(r->cx.rad, RAD_ACCESS_REQUEST) != 0) { 582 log_Printf(LogERROR, "rad_create_request: %s\n", rad_strerror(r->cx.rad)); 583 rad_close(r->cx.rad); |
559 return; | 584 return 0; |
560 } 561 562 if (rad_put_string(r->cx.rad, RAD_USER_NAME, name) != 0 || 563 rad_put_int(r->cx.rad, RAD_SERVICE_TYPE, RAD_FRAMED) != 0 || 564 rad_put_int(r->cx.rad, RAD_FRAMED_PROTOCOL, RAD_PPP) != 0) { 565 log_Printf(LogERROR, "rad_put: %s\n", rad_strerror(r->cx.rad)); 566 rad_close(r->cx.rad); | 585 } 586 587 if (rad_put_string(r->cx.rad, RAD_USER_NAME, name) != 0 || 588 rad_put_int(r->cx.rad, RAD_SERVICE_TYPE, RAD_FRAMED) != 0 || 589 rad_put_int(r->cx.rad, RAD_FRAMED_PROTOCOL, RAD_PPP) != 0) { 590 log_Printf(LogERROR, "rad_put: %s\n", rad_strerror(r->cx.rad)); 591 rad_close(r->cx.rad); |
567 return; | 592 return 0; |
568 } 569 570 switch (authp->physical->link.lcp.want_auth) { 571 case PROTO_PAP: 572 /* We're talking PAP */ 573 if (rad_put_attr(r->cx.rad, RAD_USER_PASSWORD, key, klen) != 0) { 574 log_Printf(LogERROR, "PAP: rad_put_string: %s\n", 575 rad_strerror(r->cx.rad)); 576 rad_close(r->cx.rad); | 593 } 594 595 switch (authp->physical->link.lcp.want_auth) { 596 case PROTO_PAP: 597 /* We're talking PAP */ 598 if (rad_put_attr(r->cx.rad, RAD_USER_PASSWORD, key, klen) != 0) { 599 log_Printf(LogERROR, "PAP: rad_put_string: %s\n", 600 rad_strerror(r->cx.rad)); 601 rad_close(r->cx.rad); |
577 return; | 602 return 0; |
578 } 579 break; 580 581 case PROTO_CHAP: 582 switch (authp->physical->link.lcp.want_authtype) { 583 case 0x5: 584 if (rad_put_attr(r->cx.rad, RAD_CHAP_PASSWORD, key, klen) != 0 || | 603 } 604 break; 605 606 case PROTO_CHAP: 607 switch (authp->physical->link.lcp.want_authtype) { 608 case 0x5: 609 if (rad_put_attr(r->cx.rad, RAD_CHAP_PASSWORD, key, klen) != 0 || |
585 rad_put_attr(r->cx.rad, RAD_CHAP_CHALLENGE, challenge, clen) != 0) { | 610 rad_put_attr(r->cx.rad, RAD_CHAP_CHALLENGE, nchallenge, nclen) != 0) { |
586 log_Printf(LogERROR, "CHAP: rad_put_string: %s\n", 587 rad_strerror(r->cx.rad)); 588 rad_close(r->cx.rad); | 611 log_Printf(LogERROR, "CHAP: rad_put_string: %s\n", 612 rad_strerror(r->cx.rad)); 613 rad_close(r->cx.rad); |
589 return; | 614 return 0; |
590 } 591 break; 592 593#ifndef NODES 594 case 0x80: 595 if (klen != 50) { | 615 } 616 break; 617 618#ifndef NODES 619 case 0x80: 620 if (klen != 50) { |
596 log_Printf(LogERROR, "CHAP80: Unrecognised length %d\n", klen); | 621 log_Printf(LogERROR, "CHAP80: Unrecognised key length %d\n", klen); |
597 rad_close(r->cx.rad); | 622 rad_close(r->cx.rad); |
598 return; | 623 return 0; |
599 } | 624 } |
625 |
|
600 rad_put_vendor_attr(r->cx.rad, RAD_VENDOR_MICROSOFT, | 626 rad_put_vendor_attr(r->cx.rad, RAD_VENDOR_MICROSOFT, |
601 RAD_MICROSOFT_MS_CHAP_CHALLENGE, challenge, clen); 602 msreq.ident = *key; 603 msreq.flags = 0x01; 604 memcpy(msreq.lm_response, key + 1, 24); 605 memcpy(msreq.nt_response, key + 25, 24); | 627 RAD_MICROSOFT_MS_CHAP_CHALLENGE, nchallenge, nclen); 628 msresp.ident = *key; 629 msresp.flags = 0x01; 630 memcpy(msresp.lm_response, key + 1, 24); 631 memcpy(msresp.nt_response, key + 25, 24); |
606 rad_put_vendor_attr(r->cx.rad, RAD_VENDOR_MICROSOFT, | 632 rad_put_vendor_attr(r->cx.rad, RAD_VENDOR_MICROSOFT, |
607 RAD_MICROSOFT_MS_CHAP_RESPONSE, &msreq, 50); | 633 RAD_MICROSOFT_MS_CHAP_RESPONSE, &msresp, 634 sizeof msresp); |
608 break; 609 610 case 0x81: | 635 break; 636 637 case 0x81: |
638 if (klen != 50) { 639 log_Printf(LogERROR, "CHAP81: Unrecognised key length %d\n", klen); 640 rad_close(r->cx.rad); 641 return 0; 642 } 643 644 if (pclen != sizeof msresp2.pchallenge) { 645 log_Printf(LogERROR, "CHAP81: Unrecognised peer challenge length %d\n", 646 pclen); 647 rad_close(r->cx.rad); 648 return 0; 649 } 650 651 rad_put_vendor_attr(r->cx.rad, RAD_VENDOR_MICROSOFT, 652 RAD_MICROSOFT_MS_CHAP_CHALLENGE, nchallenge, nclen); 653 msresp2.ident = *key; 654 msresp2.flags = 0x00; 655 memcpy(msresp2.response, key + 25, 24); 656 memset(msresp2.reserved, '\0', sizeof msresp2.reserved); 657 memcpy(msresp2.pchallenge, pchallenge, pclen); 658 rad_put_vendor_attr(r->cx.rad, RAD_VENDOR_MICROSOFT, 659 RAD_MICROSOFT_MS_CHAP2_RESPONSE, &msresp2, 660 sizeof msresp2); 661 break; |
|
611#endif 612 default: 613 log_Printf(LogERROR, "CHAP: Unrecognised type 0x%02x\n", 614 authp->physical->link.lcp.want_authtype); 615 rad_close(r->cx.rad); | 662#endif 663 default: 664 log_Printf(LogERROR, "CHAP: Unrecognised type 0x%02x\n", 665 authp->physical->link.lcp.want_authtype); 666 rad_close(r->cx.rad); |
616 return; | 667 return 0; |
617 } 618 } 619 620 if (gethostname(hostname, sizeof hostname) != 0) 621 log_Printf(LogERROR, "rad_put: gethostname(): %s\n", strerror(errno)); 622 else { 623 if ((hp = gethostbyname(hostname)) != NULL) { 624 hostaddr.s_addr = *(u_long *)hp->h_addr; 625 if (rad_put_addr(r->cx.rad, RAD_NAS_IP_ADDRESS, hostaddr) != 0) { 626 log_Printf(LogERROR, "rad_put: rad_put_string: %s\n", 627 rad_strerror(r->cx.rad)); 628 rad_close(r->cx.rad); | 668 } 669 } 670 671 if (gethostname(hostname, sizeof hostname) != 0) 672 log_Printf(LogERROR, "rad_put: gethostname(): %s\n", strerror(errno)); 673 else { 674 if ((hp = gethostbyname(hostname)) != NULL) { 675 hostaddr.s_addr = *(u_long *)hp->h_addr; 676 if (rad_put_addr(r->cx.rad, RAD_NAS_IP_ADDRESS, hostaddr) != 0) { 677 log_Printf(LogERROR, "rad_put: rad_put_string: %s\n", 678 rad_strerror(r->cx.rad)); 679 rad_close(r->cx.rad); |
629 return; | 680 return 0; |
630 } 631 } 632 if (rad_put_string(r->cx.rad, RAD_NAS_IDENTIFIER, hostname) != 0) { 633 log_Printf(LogERROR, "rad_put: rad_put_string: %s\n", 634 rad_strerror(r->cx.rad)); 635 rad_close(r->cx.rad); | 681 } 682 } 683 if (rad_put_string(r->cx.rad, RAD_NAS_IDENTIFIER, hostname) != 0) { 684 log_Printf(LogERROR, "rad_put: rad_put_string: %s\n", 685 rad_strerror(r->cx.rad)); 686 rad_close(r->cx.rad); |
636 return; | 687 return 0; |
637 } 638 } 639 640 radius_put_physical_details(r->cx.rad, authp->physical); 641 642 r->cx.auth = authp; 643 if ((got = rad_init_send_request(r->cx.rad, &r->cx.fd, &tv))) 644 radius_Process(r, got); 645 else { 646 log_Printf(LogPHASE, "Radius: Request sent\n"); 647 log_Printf(LogDEBUG, "Using radius_Timeout [%p]\n", radius_Timeout); 648 r->cx.timer.load = tv.tv_usec / TICKUNIT + tv.tv_sec * SECTICKS; 649 r->cx.timer.func = radius_Timeout; 650 r->cx.timer.name = "radius auth"; 651 r->cx.timer.arg = r; 652 timer_Start(&r->cx.timer); 653 } | 688 } 689 } 690 691 radius_put_physical_details(r->cx.rad, authp->physical); 692 693 r->cx.auth = authp; 694 if ((got = rad_init_send_request(r->cx.rad, &r->cx.fd, &tv))) 695 radius_Process(r, got); 696 else { 697 log_Printf(LogPHASE, "Radius: Request sent\n"); 698 log_Printf(LogDEBUG, "Using radius_Timeout [%p]\n", radius_Timeout); 699 r->cx.timer.load = tv.tv_usec / TICKUNIT + tv.tv_sec * SECTICKS; 700 r->cx.timer.func = radius_Timeout; 701 r->cx.timer.name = "radius auth"; 702 r->cx.timer.arg = r; 703 timer_Start(&r->cx.timer); 704 } |
705 706 return 1; |
|
654} 655 656/* 657 * Send an accounting request to the RADIUS server 658 */ 659void 660radius_Account(struct radius *r, struct radacct *ac, struct datalink *dl, 661 int acct_type, struct in_addr *peer_ip, struct in_addr *netmask, --- 137 unchanged lines hidden (view full) --- 799 prompt_Printf(p, " Radius config: %s", 800 *r->cfg.file ? r->cfg.file : "none"); 801 if (r->valid) { 802 prompt_Printf(p, "\n IP: %s\n", inet_ntoa(r->ip)); 803 prompt_Printf(p, " Netmask: %s\n", inet_ntoa(r->mask)); 804 prompt_Printf(p, " MTU: %lu\n", r->mtu); 805 prompt_Printf(p, " VJ: %sabled\n", r->vj ? "en" : "dis"); 806 prompt_Printf(p, " Message: %s\n", r->repstr ? r->repstr : ""); | 707} 708 709/* 710 * Send an accounting request to the RADIUS server 711 */ 712void 713radius_Account(struct radius *r, struct radacct *ac, struct datalink *dl, 714 int acct_type, struct in_addr *peer_ip, struct in_addr *netmask, --- 137 unchanged lines hidden (view full) --- 852 prompt_Printf(p, " Radius config: %s", 853 *r->cfg.file ? r->cfg.file : "none"); 854 if (r->valid) { 855 prompt_Printf(p, "\n IP: %s\n", inet_ntoa(r->ip)); 856 prompt_Printf(p, " Netmask: %s\n", inet_ntoa(r->mask)); 857 prompt_Printf(p, " MTU: %lu\n", r->mtu); 858 prompt_Printf(p, " VJ: %sabled\n", r->vj ? "en" : "dis"); 859 prompt_Printf(p, " Message: %s\n", r->repstr ? r->repstr : ""); |
860 prompt_Printf(p, " MS-CHAP2-Response: %s\n", 861 r->msrepstr ? r->msrepstr : ""); |
|
807 prompt_Printf(p, " Error Message: %s\n", r->errstr ? r->errstr : ""); 808 if (r->routes) 809 route_ShowSticky(p, r->routes, " Routes", 16); 810 } else 811 prompt_Printf(p, " (not authenticated)\n"); 812} | 862 prompt_Printf(p, " Error Message: %s\n", r->errstr ? r->errstr : ""); 863 if (r->routes) 864 route_ShowSticky(p, r->routes, " Routes", 16); 865 } else 866 prompt_Printf(p, " (not authenticated)\n"); 867} |