1 /*********************************************************************** 2 * 3 * radius.c 4 * 5 * RADIUS plugin for pppd. Performs PAP, CHAP, MS-CHAP, MS-CHAPv2 6 * authentication using RADIUS. 7 * 8 * Copyright (C) 2002 Roaring Penguin Software Inc. 9 * 10 * Based on a patch for ipppd, which is: 11 * Copyright (C) 1996, Matjaz Godec <gody (at) elgo.si> 12 * Copyright (C) 1996, Lars Fenneberg <in5y050 (at) public.uni-hamburg.de> 13 * Copyright (C) 1997, Miguel A.L. Paraz <map (at) iphil.net> 14 * 15 * Uses radiusclient library, which is: 16 * Copyright (C) 1995,1996,1997,1998 Lars Fenneberg <lf (at) elemental.net> 17 * Copyright (C) 2002 Roaring Penguin Software Inc. 18 * 19 * MPPE support is by Ralf Hofmann, <ralf.hofmann (at) elvido.net>, with 20 * modification from Frank Cusack, <frank (at) google.com>. 21 * 22 * This plugin may be distributed according to the terms of the GNU 23 * General Public License, version 2 or (at your option) any later version. 24 * 25 ***********************************************************************/ 26 static char const RCSID[] = 27 "$Id: radius.c,v 1.32 2008/05/26 09:18:08 paulus Exp $"; 28 29 #include "pppd.h" 30 #include "chap-new.h" 31 #ifdef CHAPMS 32 #include "chap_ms.h" 33 #ifdef MPPE 34 #include "md5.h" 35 #endif 36 #endif 37 #include "radiusclient.h" 38 #include "fsm.h" 39 #include "ipcp.h" 40 #include <syslog.h> 41 #include <sys/types.h> 42 #include <sys/time.h> 43 #include <string.h> 44 #include <netinet/in.h> 45 #include <stdlib.h> 46 47 #define BUF_LEN 1024 48 49 #define MD5_HASH_SIZE 16 50 51 #define MSDNS 1 52 53 static char *config_file = NULL; 54 static int add_avp(char **); 55 static struct avpopt { 56 char *vpstr; 57 struct avpopt *next; 58 } *avpopt = NULL; 59 static bool portnummap = 0; 60 61 static option_t Options[] = { 62 { "radius-config-file", o_string, &config_file }, 63 { "avpair", o_special, add_avp }, 64 { "map-to-ttyname", o_bool, &portnummap, 65 "Set Radius NAS-Port attribute value via libradiusclient library", OPT_PRIO | 1 }, 66 { "map-to-ifname", o_bool, &portnummap, 67 "Set Radius NAS-Port attribute to number as in interface name (Default)", OPT_PRIOSUB | 0 }, 68 { NULL } 69 }; 70 71 static int radius_secret_check(void); 72 static int radius_pap_auth(char *user, 73 char *passwd, 74 char **msgp, 75 struct wordlist **paddrs, 76 struct wordlist **popts); 77 static int radius_chap_verify(char *user, char *ourname, int id, 78 struct chap_digest_type *digest, 79 unsigned char *challenge, 80 unsigned char *response, 81 char *message, int message_space); 82 83 static void radius_ip_up(void *opaque, int arg); 84 static void radius_ip_down(void *opaque, int arg); 85 static void make_username_realm(char *user); 86 static int radius_setparams(VALUE_PAIR *vp, char *msg, REQUEST_INFO *req_info, 87 struct chap_digest_type *digest, 88 unsigned char *challenge, 89 char *message, int message_space); 90 static void radius_choose_ip(u_int32_t *addrp); 91 static int radius_init(char *msg); 92 static int get_client_port(char *ifname); 93 static int radius_allowed_address(u_int32_t addr); 94 static void radius_acct_interim(void *); 95 #ifdef MPPE 96 static int radius_setmppekeys(VALUE_PAIR *vp, REQUEST_INFO *req_info, 97 unsigned char *); 98 static int radius_setmppekeys2(VALUE_PAIR *vp, REQUEST_INFO *req_info); 99 #endif 100 101 #ifndef MAXSESSIONID 102 #define MAXSESSIONID 32 103 #endif 104 105 #ifndef MAXCLASSLEN 106 #define MAXCLASSLEN 500 107 #endif 108 109 struct radius_state { 110 int accounting_started; 111 int initialized; 112 int client_port; 113 int choose_ip; 114 int any_ip_addr_ok; 115 int done_chap_once; 116 u_int32_t ip_addr; 117 char user[MAXNAMELEN]; 118 char config_file[MAXPATHLEN]; 119 char session_id[MAXSESSIONID + 1]; 120 time_t start_time; 121 int acct_interim_interval; 122 SERVER *authserver; /* Authentication server to use */ 123 SERVER *acctserver; /* Accounting server to use */ 124 int class_len; 125 char class[MAXCLASSLEN]; 126 VALUE_PAIR *avp; /* Additional (user supplied) vp's to send to server */ 127 }; 128 129 void (*radius_attributes_hook)(VALUE_PAIR *) = NULL; 130 131 /* The pre_auth_hook MAY set authserver and acctserver if it wants. 132 In that case, they override the values in the radiusclient.conf file */ 133 void (*radius_pre_auth_hook)(char const *user, 134 SERVER **authserver, 135 SERVER **acctserver) = NULL; 136 137 static struct radius_state rstate; 138 139 char pppd_version[] = VERSION; 140 141 /********************************************************************** 142 * %FUNCTION: plugin_init 143 * %ARGUMENTS: 144 * None 145 * %RETURNS: 146 * Nothing 147 * %DESCRIPTION: 148 * Initializes RADIUS plugin. 149 ***********************************************************************/ 150 void 151 plugin_init(void) 152 { 153 pap_check_hook = radius_secret_check; 154 pap_auth_hook = radius_pap_auth; 155 156 chap_check_hook = radius_secret_check; 157 chap_verify_hook = radius_chap_verify; 158 159 ip_choose_hook = radius_choose_ip; 160 allowed_address_hook = radius_allowed_address; 161 162 add_notifier(&ip_up_notifier, radius_ip_up, NULL); 163 add_notifier(&ip_down_notifier, radius_ip_down, NULL); 164 165 memset(&rstate, 0, sizeof(rstate)); 166 167 strlcpy(rstate.config_file, "/etc/radiusclient/radiusclient.conf", 168 sizeof(rstate.config_file)); 169 170 add_options(Options); 171 172 info("RADIUS plugin initialized."); 173 } 174 175 /********************************************************************** 176 * %FUNCTION: add_avp 177 * %ARGUMENTS: 178 * argv -- the <attribute=value> pair to add 179 * %RETURNS: 180 * 1 181 * %DESCRIPTION: 182 * Adds an av pair to be passed on to the RADIUS server on each request. 183 ***********************************************************************/ 184 static int 185 add_avp(char **argv) 186 { 187 struct avpopt *p = malloc(sizeof(struct avpopt)); 188 189 /* Append to a list of vp's for later parsing */ 190 p->vpstr = strdup(*argv); 191 p->next = avpopt; 192 avpopt = p; 193 194 return 1; 195 } 196 197 /********************************************************************** 198 * %FUNCTION: radius_secret_check 199 * %ARGUMENTS: 200 * None 201 * %RETURNS: 202 * 1 -- we are ALWAYS willing to supply a secret. :-) 203 * %DESCRIPTION: 204 * Tells pppd that we will try to authenticate the peer, and not to 205 * worry about looking in /etc/ppp/*-secrets 206 ***********************************************************************/ 207 static int 208 radius_secret_check(void) 209 { 210 return 1; 211 } 212 213 /********************************************************************** 214 * %FUNCTION: radius_choose_ip 215 * %ARGUMENTS: 216 * addrp -- where to store the IP address 217 * %RETURNS: 218 * Nothing 219 * %DESCRIPTION: 220 * If RADIUS server has specified an IP address, it is stored in *addrp. 221 ***********************************************************************/ 222 static void 223 radius_choose_ip(u_int32_t *addrp) 224 { 225 if (rstate.choose_ip) { 226 *addrp = rstate.ip_addr; 227 } 228 } 229 230 /********************************************************************** 231 * %FUNCTION: radius_pap_auth 232 * %ARGUMENTS: 233 * user -- user-name of peer 234 * passwd -- password supplied by peer 235 * msgp -- Message which will be sent in PAP response 236 * paddrs -- set to a list of possible peer IP addresses 237 * popts -- set to a list of additional pppd options 238 * %RETURNS: 239 * 1 if we can authenticate, -1 if we cannot. 240 * %DESCRIPTION: 241 * Performs PAP authentication using RADIUS 242 ***********************************************************************/ 243 static int 244 radius_pap_auth(char *user, 245 char *passwd, 246 char **msgp, 247 struct wordlist **paddrs, 248 struct wordlist **popts) 249 { 250 VALUE_PAIR *send, *received; 251 UINT4 av_type; 252 int result; 253 static char radius_msg[BUF_LEN]; 254 255 radius_msg[0] = 0; 256 *msgp = radius_msg; 257 258 if (radius_init(radius_msg) < 0) { 259 return 0; 260 } 261 262 /* Put user with potentially realm added in rstate.user */ 263 make_username_realm(user); 264 265 if (radius_pre_auth_hook) { 266 radius_pre_auth_hook(rstate.user, 267 &rstate.authserver, 268 &rstate.acctserver); 269 } 270 271 send = NULL; 272 received = NULL; 273 274 /* Hack... the "port" is the ppp interface number. Should really be 275 the tty */ 276 rstate.client_port = get_client_port(portnummap ? devnam : ifname); 277 278 av_type = PW_FRAMED; 279 rc_avpair_add(&send, PW_SERVICE_TYPE, &av_type, 0, VENDOR_NONE); 280 281 av_type = PW_PPP; 282 rc_avpair_add(&send, PW_FRAMED_PROTOCOL, &av_type, 0, VENDOR_NONE); 283 284 rc_avpair_add(&send, PW_USER_NAME, rstate.user , 0, VENDOR_NONE); 285 rc_avpair_add(&send, PW_USER_PASSWORD, passwd, 0, VENDOR_NONE); 286 if (*remote_number) { 287 rc_avpair_add(&send, PW_CALLING_STATION_ID, remote_number, 0, 288 VENDOR_NONE); 289 } else if (ipparam) 290 rc_avpair_add(&send, PW_CALLING_STATION_ID, ipparam, 0, VENDOR_NONE); 291 292 /* Add user specified vp's */ 293 if (rstate.avp) 294 rc_avpair_insert(&send, NULL, rc_avpair_copy(rstate.avp)); 295 296 if (rstate.authserver) { 297 result = rc_auth_using_server(rstate.authserver, 298 rstate.client_port, send, 299 &received, radius_msg, NULL); 300 } else { 301 result = rc_auth(rstate.client_port, send, &received, radius_msg, NULL); 302 } 303 304 if (result == OK_RC) { 305 if (radius_setparams(received, radius_msg, NULL, NULL, NULL, NULL, 0) < 0) { 306 result = ERROR_RC; 307 } 308 } 309 310 /* free value pairs */ 311 rc_avpair_free(received); 312 rc_avpair_free(send); 313 314 return (result == OK_RC) ? 1 : 0; 315 } 316 317 /********************************************************************** 318 * %FUNCTION: radius_chap_verify 319 * %ARGUMENTS: 320 * user -- name of the peer 321 * ourname -- name for this machine 322 * id -- the ID byte in the challenge 323 * digest -- points to the structure representing the digest type 324 * challenge -- the challenge string we sent (length in first byte) 325 * response -- the response (hash) the peer sent back (length in 1st byte) 326 * message -- space for a message to be returned to the peer 327 * message_space -- number of bytes available at *message. 328 * %RETURNS: 329 * 1 if the response is good, 0 if it is bad 330 * %DESCRIPTION: 331 * Performs CHAP, MS-CHAP and MS-CHAPv2 authentication using RADIUS. 332 ***********************************************************************/ 333 static int 334 radius_chap_verify(char *user, char *ourname, int id, 335 struct chap_digest_type *digest, 336 unsigned char *challenge, unsigned char *response, 337 char *message, int message_space) 338 { 339 VALUE_PAIR *send, *received; 340 UINT4 av_type; 341 static char radius_msg[BUF_LEN]; 342 int result; 343 int challenge_len, response_len; 344 u_char cpassword[MAX_RESPONSE_LEN + 1]; 345 #ifdef MPPE 346 /* Need the RADIUS secret and Request Authenticator to decode MPPE */ 347 REQUEST_INFO request_info, *req_info = &request_info; 348 #else 349 REQUEST_INFO *req_info = NULL; 350 #endif 351 352 challenge_len = *challenge++; 353 response_len = *response++; 354 355 radius_msg[0] = 0; 356 357 if (radius_init(radius_msg) < 0) { 358 error("%s", radius_msg); 359 return 0; 360 } 361 362 /* return error for types we can't handle */ 363 if ((digest->code != CHAP_MD5) 364 #ifdef CHAPMS 365 && (digest->code != CHAP_MICROSOFT) 366 && (digest->code != CHAP_MICROSOFT_V2) 367 #endif 368 ) { 369 error("RADIUS: Challenge type %u unsupported", digest->code); 370 return 0; 371 } 372 373 /* Put user with potentially realm added in rstate.user */ 374 if (!rstate.done_chap_once) { 375 make_username_realm(user); 376 rstate.client_port = get_client_port (portnummap ? devnam : ifname); 377 if (radius_pre_auth_hook) { 378 radius_pre_auth_hook(rstate.user, 379 &rstate.authserver, 380 &rstate.acctserver); 381 } 382 } 383 384 send = received = NULL; 385 386 av_type = PW_FRAMED; 387 rc_avpair_add (&send, PW_SERVICE_TYPE, &av_type, 0, VENDOR_NONE); 388 389 av_type = PW_PPP; 390 rc_avpair_add (&send, PW_FRAMED_PROTOCOL, &av_type, 0, VENDOR_NONE); 391 392 rc_avpair_add (&send, PW_USER_NAME, rstate.user , 0, VENDOR_NONE); 393 394 /* 395 * add the challenge and response fields 396 */ 397 switch (digest->code) { 398 case CHAP_MD5: 399 /* CHAP-Challenge and CHAP-Password */ 400 if (response_len != MD5_HASH_SIZE) 401 return 0; 402 cpassword[0] = id; 403 memcpy(&cpassword[1], response, MD5_HASH_SIZE); 404 405 rc_avpair_add(&send, PW_CHAP_CHALLENGE, 406 challenge, challenge_len, VENDOR_NONE); 407 rc_avpair_add(&send, PW_CHAP_PASSWORD, 408 cpassword, MD5_HASH_SIZE + 1, VENDOR_NONE); 409 break; 410 411 #ifdef CHAPMS 412 case CHAP_MICROSOFT: 413 { 414 /* MS-CHAP-Challenge and MS-CHAP-Response */ 415 u_char *p = cpassword; 416 417 if (response_len != MS_CHAP_RESPONSE_LEN) 418 return 0; 419 *p++ = id; 420 /* The idiots use a different field order in RADIUS than PPP */ 421 *p++ = response[MS_CHAP_USENT]; 422 memcpy(p, response, MS_CHAP_LANMANRESP_LEN + MS_CHAP_NTRESP_LEN); 423 424 rc_avpair_add(&send, PW_MS_CHAP_CHALLENGE, 425 challenge, challenge_len, VENDOR_MICROSOFT); 426 rc_avpair_add(&send, PW_MS_CHAP_RESPONSE, 427 cpassword, MS_CHAP_RESPONSE_LEN + 1, VENDOR_MICROSOFT); 428 break; 429 } 430 431 case CHAP_MICROSOFT_V2: 432 { 433 /* MS-CHAP-Challenge and MS-CHAP2-Response */ 434 u_char *p = cpassword; 435 436 if (response_len != MS_CHAP2_RESPONSE_LEN) 437 return 0; 438 *p++ = id; 439 /* The idiots use a different field order in RADIUS than PPP */ 440 *p++ = response[MS_CHAP2_FLAGS]; 441 memcpy(p, response, (MS_CHAP2_PEER_CHAL_LEN + MS_CHAP2_RESERVED_LEN 442 + MS_CHAP2_NTRESP_LEN)); 443 444 rc_avpair_add(&send, PW_MS_CHAP_CHALLENGE, 445 challenge, challenge_len, VENDOR_MICROSOFT); 446 rc_avpair_add(&send, PW_MS_CHAP2_RESPONSE, 447 cpassword, MS_CHAP2_RESPONSE_LEN + 1, VENDOR_MICROSOFT); 448 break; 449 } 450 #endif 451 } 452 453 if (*remote_number) { 454 rc_avpair_add(&send, PW_CALLING_STATION_ID, remote_number, 0, 455 VENDOR_NONE); 456 } else if (ipparam) 457 rc_avpair_add(&send, PW_CALLING_STATION_ID, ipparam, 0, VENDOR_NONE); 458 459 /* Add user specified vp's */ 460 if (rstate.avp) 461 rc_avpair_insert(&send, NULL, rc_avpair_copy(rstate.avp)); 462 463 /* 464 * make authentication with RADIUS server 465 */ 466 467 if (rstate.authserver) { 468 result = rc_auth_using_server(rstate.authserver, 469 rstate.client_port, send, 470 &received, radius_msg, req_info); 471 } else { 472 result = rc_auth(rstate.client_port, send, &received, radius_msg, 473 req_info); 474 } 475 476 strlcpy(message, radius_msg, message_space); 477 478 if (result == OK_RC) { 479 if (!rstate.done_chap_once) { 480 if (radius_setparams(received, radius_msg, req_info, digest, 481 challenge, message, message_space) < 0) { 482 error("%s", radius_msg); 483 result = ERROR_RC; 484 } else { 485 rstate.done_chap_once = 1; 486 } 487 } 488 } 489 490 rc_avpair_free(received); 491 rc_avpair_free (send); 492 return (result == OK_RC); 493 } 494 495 /********************************************************************** 496 * %FUNCTION: make_username_realm 497 * %ARGUMENTS: 498 * user -- the user given to pppd 499 * %RETURNS: 500 * Nothing 501 * %DESCRIPTION: 502 * Copies user into rstate.user. If it lacks a realm (no "@domain" part), 503 * then the default realm from the radiusclient config file is added. 504 ***********************************************************************/ 505 static void 506 make_username_realm(char *user) 507 { 508 char *default_realm; 509 510 if ( user != NULL ) { 511 strlcpy(rstate.user, user, sizeof(rstate.user)); 512 } else { 513 rstate.user[0] = 0; 514 } 515 516 default_realm = rc_conf_str("default_realm"); 517 518 if (!strchr(rstate.user, '@') && 519 default_realm && 520 (*default_realm != '\0')) { 521 strlcat(rstate.user, "@", sizeof(rstate.user)); 522 strlcat(rstate.user, default_realm, sizeof(rstate.user)); 523 } 524 } 525 526 /********************************************************************** 527 * %FUNCTION: radius_setparams 528 * %ARGUMENTS: 529 * vp -- received value-pairs 530 * msg -- buffer in which to place error message. Holds up to BUF_LEN chars 531 * %RETURNS: 532 * >= 0 on success; -1 on failure 533 * %DESCRIPTION: 534 * Parses attributes sent by RADIUS server and sets them in pppd. 535 ***********************************************************************/ 536 static int 537 radius_setparams(VALUE_PAIR *vp, char *msg, REQUEST_INFO *req_info, 538 struct chap_digest_type *digest, unsigned char *challenge, 539 char *message, int message_space) 540 { 541 u_int32_t remote; 542 int ms_chap2_success = 0; 543 #ifdef MPPE 544 int mppe_enc_keys = 0; /* whether or not these were received */ 545 int mppe_enc_policy = 0; 546 int mppe_enc_types = 0; 547 #endif 548 #ifdef MSDNS 549 ipcp_options *wo = &ipcp_wantoptions[0]; 550 ipcp_options *ao = &ipcp_allowoptions[0]; 551 int got_msdns_1 = 0; 552 int got_msdns_2 = 0; 553 int got_wins_1 = 0; 554 int got_wins_2 = 0; 555 #endif 556 557 /* Send RADIUS attributes to anyone else who might be interested */ 558 if (radius_attributes_hook) { 559 (*radius_attributes_hook)(vp); 560 } 561 562 /* 563 * service type (if not framed then quit), 564 * new IP address (RADIUS can define static IP for some users), 565 */ 566 567 while (vp) { 568 if (vp->vendorcode == VENDOR_NONE) { 569 switch (vp->attribute) { 570 case PW_SERVICE_TYPE: 571 /* check for service type */ 572 /* if not FRAMED then exit */ 573 if (vp->lvalue != PW_FRAMED) { 574 slprintf(msg, BUF_LEN, "RADIUS: wrong service type %ld for %s", 575 vp->lvalue, rstate.user); 576 return -1; 577 } 578 break; 579 580 case PW_FRAMED_PROTOCOL: 581 /* check for framed protocol type */ 582 /* if not PPP then also exit */ 583 if (vp->lvalue != PW_PPP) { 584 slprintf(msg, BUF_LEN, "RADIUS: wrong framed protocol %ld for %s", 585 vp->lvalue, rstate.user); 586 return -1; 587 } 588 break; 589 590 case PW_SESSION_TIMEOUT: 591 /* Session timeout */ 592 maxconnect = vp->lvalue; 593 break; 594 case PW_FILTER_ID: 595 /* packet filter, will be handled via ip-(up|down) script */ 596 script_setenv("RADIUS_FILTER_ID", vp->strvalue, 1); 597 break; 598 case PW_FRAMED_ROUTE: 599 /* route, will be handled via ip-(up|down) script */ 600 script_setenv("RADIUS_FRAMED_ROUTE", vp->strvalue, 1); 601 break; 602 case PW_IDLE_TIMEOUT: 603 /* idle parameter */ 604 idle_time_limit = vp->lvalue; 605 break; 606 #ifdef MAXOCTETS 607 case PW_SESSION_OCTETS_LIMIT: 608 /* Session traffic limit */ 609 maxoctets = vp->lvalue; 610 break; 611 case PW_OCTETS_DIRECTION: 612 /* Session traffic limit direction check */ 613 maxoctets_dir = ( vp->lvalue > 4 ) ? 0 : vp->lvalue ; 614 break; 615 #endif 616 case PW_ACCT_INTERIM_INTERVAL: 617 /* Send accounting updates every few seconds */ 618 rstate.acct_interim_interval = vp->lvalue; 619 /* RFC says it MUST NOT be less than 60 seconds */ 620 /* We use "0" to signify not sending updates */ 621 if (rstate.acct_interim_interval && 622 rstate.acct_interim_interval < 60) { 623 rstate.acct_interim_interval = 60; 624 } 625 break; 626 case PW_FRAMED_IP_ADDRESS: 627 /* seting up remote IP addresses */ 628 remote = vp->lvalue; 629 if (remote == 0xffffffff) { 630 /* 0xffffffff means user should be allowed to select one */ 631 rstate.any_ip_addr_ok = 1; 632 } else if (remote != 0xfffffffe) { 633 /* 0xfffffffe means NAS should select an ip address */ 634 remote = htonl(vp->lvalue); 635 if (bad_ip_adrs (remote)) { 636 slprintf(msg, BUF_LEN, "RADIUS: bad remote IP address %I for %s", 637 remote, rstate.user); 638 return -1; 639 } 640 rstate.choose_ip = 1; 641 rstate.ip_addr = remote; 642 } 643 break; 644 case PW_NAS_IP_ADDRESS: 645 wo->ouraddr = htonl(vp->lvalue); 646 break; 647 case PW_CLASS: 648 /* Save Class attribute to pass it in accounting request */ 649 if (vp->lvalue <= MAXCLASSLEN) { 650 rstate.class_len=vp->lvalue; 651 memcpy(rstate.class, vp->strvalue, rstate.class_len); 652 } /* else too big for our buffer - ignore it */ 653 break; 654 } 655 656 657 } else if (vp->vendorcode == VENDOR_MICROSOFT) { 658 #ifdef CHAPMS 659 switch (vp->attribute) { 660 case PW_MS_CHAP2_SUCCESS: 661 if ((vp->lvalue != 43) || strncmp(vp->strvalue + 1, "S=", 2)) { 662 slprintf(msg,BUF_LEN,"RADIUS: bad MS-CHAP2-Success packet"); 663 return -1; 664 } 665 if (message != NULL) 666 strlcpy(message, vp->strvalue + 1, message_space); 667 ms_chap2_success = 1; 668 break; 669 670 #ifdef MPPE 671 case PW_MS_CHAP_MPPE_KEYS: 672 if (radius_setmppekeys(vp, req_info, challenge) < 0) { 673 slprintf(msg, BUF_LEN, 674 "RADIUS: bad MS-CHAP-MPPE-Keys attribute"); 675 return -1; 676 } 677 mppe_enc_keys = 1; 678 break; 679 680 case PW_MS_MPPE_SEND_KEY: 681 case PW_MS_MPPE_RECV_KEY: 682 if (radius_setmppekeys2(vp, req_info) < 0) { 683 slprintf(msg, BUF_LEN, 684 "RADIUS: bad MS-MPPE-%s-Key attribute", 685 (vp->attribute == PW_MS_MPPE_SEND_KEY)? 686 "Send": "Recv"); 687 return -1; 688 } 689 mppe_enc_keys = 1; 690 break; 691 692 case PW_MS_MPPE_ENCRYPTION_POLICY: 693 mppe_enc_policy = vp->lvalue; /* save for later */ 694 break; 695 696 case PW_MS_MPPE_ENCRYPTION_TYPES: 697 mppe_enc_types = vp->lvalue; /* save for later */ 698 break; 699 700 #endif /* MPPE */ 701 #ifdef MSDNS 702 case PW_MS_PRIMARY_DNS_SERVER: 703 ao->dnsaddr[0] = htonl(vp->lvalue); 704 got_msdns_1 = 1; 705 if (!got_msdns_2) 706 ao->dnsaddr[1] = ao->dnsaddr[0]; 707 break; 708 case PW_MS_SECONDARY_DNS_SERVER: 709 ao->dnsaddr[1] = htonl(vp->lvalue); 710 got_msdns_2 = 1; 711 if (!got_msdns_1) 712 ao->dnsaddr[0] = ao->dnsaddr[1]; 713 break; 714 case PW_MS_PRIMARY_NBNS_SERVER: 715 ao->winsaddr[0] = htonl(vp->lvalue); 716 got_wins_1 = 1; 717 if (!got_wins_2) 718 ao->winsaddr[1] = ao->winsaddr[0]; 719 break; 720 case PW_MS_SECONDARY_NBNS_SERVER: 721 ao->winsaddr[1] = htonl(vp->lvalue); 722 got_wins_2 = 1; 723 if (!got_wins_1) 724 ao->winsaddr[0] = ao->winsaddr[1]; 725 break; 726 #endif /* MSDNS */ 727 } 728 #endif /* CHAPMS */ 729 } 730 vp = vp->next; 731 } 732 733 /* Require a valid MS-CHAP2-SUCCESS for MS-CHAPv2 auth */ 734 if (digest && (digest->code == CHAP_MICROSOFT_V2) && !ms_chap2_success) 735 return -1; 736 737 #ifdef MPPE 738 /* 739 * Require both policy and key attributes to indicate a valid key. 740 * Note that if the policy value was '0' we don't set the key! 741 */ 742 if (mppe_enc_policy && mppe_enc_keys) { 743 mppe_keys_set = 1; 744 /* Set/modify allowed encryption types. */ 745 if (mppe_enc_types) 746 set_mppe_enc_types(mppe_enc_policy, mppe_enc_types); 747 } 748 #endif 749 750 return 0; 751 } 752 753 #ifdef MPPE 754 /********************************************************************** 755 * %FUNCTION: radius_setmppekeys 756 * %ARGUMENTS: 757 * vp -- value pair holding MS-CHAP-MPPE-KEYS attribute 758 * req_info -- radius request information used for encryption 759 * %RETURNS: 760 * >= 0 on success; -1 on failure 761 * %DESCRIPTION: 762 * Decrypt the "key" provided by the RADIUS server for MPPE encryption. 763 * See RFC 2548. 764 ***********************************************************************/ 765 static int 766 radius_setmppekeys(VALUE_PAIR *vp, REQUEST_INFO *req_info, 767 unsigned char *challenge) 768 { 769 int i; 770 MD5_CTX Context; 771 u_char plain[32]; 772 u_char buf[16]; 773 774 if (vp->lvalue != 32) { 775 error("RADIUS: Incorrect attribute length (%d) for MS-CHAP-MPPE-Keys", 776 vp->lvalue); 777 return -1; 778 } 779 780 memcpy(plain, vp->strvalue, sizeof(plain)); 781 782 MD5_Init(&Context); 783 MD5_Update(&Context, req_info->secret, strlen(req_info->secret)); 784 MD5_Update(&Context, req_info->request_vector, AUTH_VECTOR_LEN); 785 MD5_Final(buf, &Context); 786 787 for (i = 0; i < 16; i++) 788 plain[i] ^= buf[i]; 789 790 MD5_Init(&Context); 791 MD5_Update(&Context, req_info->secret, strlen(req_info->secret)); 792 MD5_Update(&Context, vp->strvalue, 16); 793 MD5_Final(buf, &Context); 794 795 for(i = 0; i < 16; i++) 796 plain[i + 16] ^= buf[i]; 797 798 /* 799 * Annoying. The "key" returned is just the NTPasswordHashHash, which 800 * the NAS (us) doesn't need; we only need the start key. So we have 801 * to generate the start key, sigh. NB: We do not support the LM-Key. 802 */ 803 mppe_set_keys(challenge, &plain[8]); 804 805 return 0; 806 } 807 808 /********************************************************************** 809 * %FUNCTION: radius_setmppekeys2 810 * %ARGUMENTS: 811 * vp -- value pair holding MS-MPPE-SEND-KEY or MS-MPPE-RECV-KEY attribute 812 * req_info -- radius request information used for encryption 813 * %RETURNS: 814 * >= 0 on success; -1 on failure 815 * %DESCRIPTION: 816 * Decrypt the key provided by the RADIUS server for MPPE encryption. 817 * See RFC 2548. 818 ***********************************************************************/ 819 static int 820 radius_setmppekeys2(VALUE_PAIR *vp, REQUEST_INFO *req_info) 821 { 822 int i; 823 MD5_CTX Context; 824 u_char *salt = vp->strvalue; 825 u_char *crypt = vp->strvalue + 2; 826 u_char plain[32]; 827 u_char buf[MD5_HASH_SIZE]; 828 char *type = "Send"; 829 830 if (vp->attribute == PW_MS_MPPE_RECV_KEY) 831 type = "Recv"; 832 833 if (vp->lvalue != 34) { 834 error("RADIUS: Incorrect attribute length (%d) for MS-MPPE-%s-Key", 835 vp->lvalue, type); 836 return -1; 837 } 838 839 if ((salt[0] & 0x80) == 0) { 840 error("RADIUS: Illegal salt value for MS-MPPE-%s-Key attribute", type); 841 return -1; 842 } 843 844 memcpy(plain, crypt, 32); 845 846 MD5_Init(&Context); 847 MD5_Update(&Context, req_info->secret, strlen(req_info->secret)); 848 MD5_Update(&Context, req_info->request_vector, AUTH_VECTOR_LEN); 849 MD5_Update(&Context, salt, 2); 850 MD5_Final(buf, &Context); 851 852 for (i = 0; i < 16; i++) 853 plain[i] ^= buf[i]; 854 855 if (plain[0] != sizeof(mppe_send_key) /* 16 */) { 856 error("RADIUS: Incorrect key length (%d) for MS-MPPE-%s-Key attribute", 857 (int) plain[0], type); 858 return -1; 859 } 860 861 MD5_Init(&Context); 862 MD5_Update(&Context, req_info->secret, strlen(req_info->secret)); 863 MD5_Update(&Context, crypt, 16); 864 MD5_Final(buf, &Context); 865 866 plain[16] ^= buf[0]; /* only need the first byte */ 867 868 if (vp->attribute == PW_MS_MPPE_SEND_KEY) 869 memcpy(mppe_send_key, plain + 1, 16); 870 else 871 memcpy(mppe_recv_key, plain + 1, 16); 872 873 return 0; 874 } 875 #endif /* MPPE */ 876 877 /********************************************************************** 878 * %FUNCTION: radius_acct_start 879 * %ARGUMENTS: 880 * None 881 * %RETURNS: 882 * Nothing 883 * %DESCRIPTION: 884 * Sends a "start" accounting message to the RADIUS server. 885 ***********************************************************************/ 886 static void 887 radius_acct_start(void) 888 { 889 UINT4 av_type; 890 int result; 891 VALUE_PAIR *send = NULL; 892 ipcp_options *ho = &ipcp_hisoptions[0]; 893 u_int32_t hisaddr; 894 895 if (!rstate.initialized) { 896 return; 897 } 898 899 rstate.start_time = time(NULL); 900 901 strncpy(rstate.session_id, rc_mksid(), sizeof(rstate.session_id)); 902 903 rc_avpair_add(&send, PW_ACCT_SESSION_ID, 904 rstate.session_id, 0, VENDOR_NONE); 905 rc_avpair_add(&send, PW_USER_NAME, 906 rstate.user, 0, VENDOR_NONE); 907 908 if (rstate.class_len > 0) 909 rc_avpair_add(&send, PW_CLASS, 910 rstate.class, rstate.class_len, VENDOR_NONE); 911 912 av_type = PW_STATUS_START; 913 rc_avpair_add(&send, PW_ACCT_STATUS_TYPE, &av_type, 0, VENDOR_NONE); 914 915 av_type = PW_FRAMED; 916 rc_avpair_add(&send, PW_SERVICE_TYPE, &av_type, 0, VENDOR_NONE); 917 918 av_type = PW_PPP; 919 rc_avpair_add(&send, PW_FRAMED_PROTOCOL, &av_type, 0, VENDOR_NONE); 920 921 if (*remote_number) { 922 rc_avpair_add(&send, PW_CALLING_STATION_ID, 923 remote_number, 0, VENDOR_NONE); 924 } else if (ipparam) 925 rc_avpair_add(&send, PW_CALLING_STATION_ID, ipparam, 0, VENDOR_NONE); 926 927 av_type = PW_RADIUS; 928 rc_avpair_add(&send, PW_ACCT_AUTHENTIC, &av_type, 0, VENDOR_NONE); 929 930 931 av_type = ( using_pty ? PW_VIRTUAL : ( sync_serial ? PW_SYNC : PW_ASYNC ) ); 932 rc_avpair_add(&send, PW_NAS_PORT_TYPE, &av_type, 0, VENDOR_NONE); 933 934 hisaddr = ho->hisaddr; 935 av_type = htonl(hisaddr); 936 rc_avpair_add(&send, PW_FRAMED_IP_ADDRESS , &av_type , 0, VENDOR_NONE); 937 938 /* Add user specified vp's */ 939 if (rstate.avp) 940 rc_avpair_insert(&send, NULL, rc_avpair_copy(rstate.avp)); 941 942 if (rstate.acctserver) { 943 result = rc_acct_using_server(rstate.acctserver, 944 rstate.client_port, send); 945 } else { 946 result = rc_acct(rstate.client_port, send); 947 } 948 949 rc_avpair_free(send); 950 951 if (result != OK_RC) { 952 /* RADIUS server could be down so make this a warning */ 953 syslog(LOG_WARNING, 954 "Accounting START failed for %s", rstate.user); 955 } else { 956 rstate.accounting_started = 1; 957 /* Kick off periodic accounting reports */ 958 if (rstate.acct_interim_interval) { 959 TIMEOUT(radius_acct_interim, NULL, rstate.acct_interim_interval); 960 } 961 } 962 } 963 964 /********************************************************************** 965 * %FUNCTION: radius_acct_stop 966 * %ARGUMENTS: 967 * None 968 * %RETURNS: 969 * Nothing 970 * %DESCRIPTION: 971 * Sends a "stop" accounting message to the RADIUS server. 972 ***********************************************************************/ 973 static void 974 radius_acct_stop(void) 975 { 976 UINT4 av_type; 977 VALUE_PAIR *send = NULL; 978 ipcp_options *ho = &ipcp_hisoptions[0]; 979 u_int32_t hisaddr; 980 int result; 981 982 if (!rstate.initialized) { 983 return; 984 } 985 986 if (!rstate.accounting_started) { 987 return; 988 } 989 990 if (rstate.acct_interim_interval) 991 UNTIMEOUT(radius_acct_interim, NULL); 992 993 rstate.accounting_started = 0; 994 rc_avpair_add(&send, PW_ACCT_SESSION_ID, rstate.session_id, 995 0, VENDOR_NONE); 996 997 rc_avpair_add(&send, PW_USER_NAME, rstate.user, 0, VENDOR_NONE); 998 999 av_type = PW_STATUS_STOP; 1000 rc_avpair_add(&send, PW_ACCT_STATUS_TYPE, &av_type, 0, VENDOR_NONE); 1001 1002 av_type = PW_FRAMED; 1003 rc_avpair_add(&send, PW_SERVICE_TYPE, &av_type, 0, VENDOR_NONE); 1004 1005 av_type = PW_PPP; 1006 rc_avpair_add(&send, PW_FRAMED_PROTOCOL, &av_type, 0, VENDOR_NONE); 1007 1008 av_type = PW_RADIUS; 1009 rc_avpair_add(&send, PW_ACCT_AUTHENTIC, &av_type, 0, VENDOR_NONE); 1010 1011 1012 if (link_stats_valid) { 1013 av_type = link_connect_time; 1014 rc_avpair_add(&send, PW_ACCT_SESSION_TIME, &av_type, 0, VENDOR_NONE); 1015 1016 av_type = link_stats.bytes_out; 1017 rc_avpair_add(&send, PW_ACCT_OUTPUT_OCTETS, &av_type, 0, VENDOR_NONE); 1018 1019 av_type = link_stats.bytes_in; 1020 rc_avpair_add(&send, PW_ACCT_INPUT_OCTETS, &av_type, 0, VENDOR_NONE); 1021 1022 av_type = link_stats.pkts_out; 1023 rc_avpair_add(&send, PW_ACCT_OUTPUT_PACKETS, &av_type, 0, VENDOR_NONE); 1024 1025 av_type = link_stats.pkts_in; 1026 rc_avpair_add(&send, PW_ACCT_INPUT_PACKETS, &av_type, 0, VENDOR_NONE); 1027 } 1028 1029 if (*remote_number) { 1030 rc_avpair_add(&send, PW_CALLING_STATION_ID, 1031 remote_number, 0, VENDOR_NONE); 1032 } else if (ipparam) 1033 rc_avpair_add(&send, PW_CALLING_STATION_ID, ipparam, 0, VENDOR_NONE); 1034 1035 av_type = ( using_pty ? PW_VIRTUAL : ( sync_serial ? PW_SYNC : PW_ASYNC ) ); 1036 rc_avpair_add(&send, PW_NAS_PORT_TYPE, &av_type, 0, VENDOR_NONE); 1037 1038 av_type = PW_NAS_ERROR; 1039 switch( status ) { 1040 case EXIT_OK: 1041 case EXIT_USER_REQUEST: 1042 av_type = PW_USER_REQUEST; 1043 break; 1044 1045 case EXIT_HANGUP: 1046 case EXIT_PEER_DEAD: 1047 case EXIT_CONNECT_FAILED: 1048 av_type = PW_LOST_CARRIER; 1049 break; 1050 1051 case EXIT_INIT_FAILED: 1052 case EXIT_OPEN_FAILED: 1053 case EXIT_LOCK_FAILED: 1054 case EXIT_PTYCMD_FAILED: 1055 av_type = PW_PORT_ERROR; 1056 break; 1057 1058 case EXIT_PEER_AUTH_FAILED: 1059 case EXIT_AUTH_TOPEER_FAILED: 1060 case EXIT_NEGOTIATION_FAILED: 1061 case EXIT_CNID_AUTH_FAILED: 1062 av_type = PW_SERVICE_UNAVAILABLE; 1063 break; 1064 1065 case EXIT_IDLE_TIMEOUT: 1066 av_type = PW_ACCT_IDLE_TIMEOUT; 1067 break; 1068 1069 case EXIT_CALLBACK: 1070 av_type = PW_CALLBACK; 1071 break; 1072 1073 case EXIT_CONNECT_TIME: 1074 av_type = PW_ACCT_SESSION_TIMEOUT; 1075 break; 1076 1077 #ifdef MAXOCTETS 1078 case EXIT_TRAFFIC_LIMIT: 1079 av_type = PW_NAS_REQUEST; 1080 break; 1081 #endif 1082 1083 default: 1084 av_type = PW_NAS_ERROR; 1085 break; 1086 } 1087 rc_avpair_add(&send, PW_ACCT_TERMINATE_CAUSE, &av_type, 0, VENDOR_NONE); 1088 1089 hisaddr = ho->hisaddr; 1090 av_type = htonl(hisaddr); 1091 rc_avpair_add(&send, PW_FRAMED_IP_ADDRESS , &av_type , 0, VENDOR_NONE); 1092 1093 /* Add user specified vp's */ 1094 if (rstate.avp) 1095 rc_avpair_insert(&send, NULL, rc_avpair_copy(rstate.avp)); 1096 1097 if (rstate.acctserver) { 1098 result = rc_acct_using_server(rstate.acctserver, 1099 rstate.client_port, send); 1100 } else { 1101 result = rc_acct(rstate.client_port, send); 1102 } 1103 1104 if (result != OK_RC) { 1105 /* RADIUS server could be down so make this a warning */ 1106 syslog(LOG_WARNING, 1107 "Accounting STOP failed for %s", rstate.user); 1108 } 1109 rc_avpair_free(send); 1110 } 1111 1112 /********************************************************************** 1113 * %FUNCTION: radius_acct_interim 1114 * %ARGUMENTS: 1115 * None 1116 * %RETURNS: 1117 * Nothing 1118 * %DESCRIPTION: 1119 * Sends an interim accounting message to the RADIUS server 1120 ***********************************************************************/ 1121 static void 1122 radius_acct_interim(void *ignored) 1123 { 1124 UINT4 av_type; 1125 VALUE_PAIR *send = NULL; 1126 ipcp_options *ho = &ipcp_hisoptions[0]; 1127 u_int32_t hisaddr; 1128 int result; 1129 1130 if (!rstate.initialized) { 1131 return; 1132 } 1133 1134 if (!rstate.accounting_started) { 1135 return; 1136 } 1137 1138 rc_avpair_add(&send, PW_ACCT_SESSION_ID, rstate.session_id, 1139 0, VENDOR_NONE); 1140 1141 rc_avpair_add(&send, PW_USER_NAME, rstate.user, 0, VENDOR_NONE); 1142 1143 av_type = PW_STATUS_ALIVE; 1144 rc_avpair_add(&send, PW_ACCT_STATUS_TYPE, &av_type, 0, VENDOR_NONE); 1145 1146 av_type = PW_FRAMED; 1147 rc_avpair_add(&send, PW_SERVICE_TYPE, &av_type, 0, VENDOR_NONE); 1148 1149 av_type = PW_PPP; 1150 rc_avpair_add(&send, PW_FRAMED_PROTOCOL, &av_type, 0, VENDOR_NONE); 1151 1152 av_type = PW_RADIUS; 1153 rc_avpair_add(&send, PW_ACCT_AUTHENTIC, &av_type, 0, VENDOR_NONE); 1154 1155 /* Update link stats */ 1156 update_link_stats(0); 1157 1158 if (link_stats_valid) { 1159 link_stats_valid = 0; /* Force later code to update */ 1160 1161 av_type = link_connect_time; 1162 rc_avpair_add(&send, PW_ACCT_SESSION_TIME, &av_type, 0, VENDOR_NONE); 1163 1164 av_type = link_stats.bytes_out; 1165 rc_avpair_add(&send, PW_ACCT_OUTPUT_OCTETS, &av_type, 0, VENDOR_NONE); 1166 1167 av_type = link_stats.bytes_in; 1168 rc_avpair_add(&send, PW_ACCT_INPUT_OCTETS, &av_type, 0, VENDOR_NONE); 1169 1170 av_type = link_stats.pkts_out; 1171 rc_avpair_add(&send, PW_ACCT_OUTPUT_PACKETS, &av_type, 0, VENDOR_NONE); 1172 1173 av_type = link_stats.pkts_in; 1174 rc_avpair_add(&send, PW_ACCT_INPUT_PACKETS, &av_type, 0, VENDOR_NONE); 1175 } 1176 1177 if (*remote_number) { 1178 rc_avpair_add(&send, PW_CALLING_STATION_ID, 1179 remote_number, 0, VENDOR_NONE); 1180 } else if (ipparam) 1181 rc_avpair_add(&send, PW_CALLING_STATION_ID, ipparam, 0, VENDOR_NONE); 1182 1183 av_type = ( using_pty ? PW_VIRTUAL : ( sync_serial ? PW_SYNC : PW_ASYNC ) ); 1184 rc_avpair_add(&send, PW_NAS_PORT_TYPE, &av_type, 0, VENDOR_NONE); 1185 1186 hisaddr = ho->hisaddr; 1187 av_type = htonl(hisaddr); 1188 rc_avpair_add(&send, PW_FRAMED_IP_ADDRESS , &av_type , 0, VENDOR_NONE); 1189 1190 /* Add user specified vp's */ 1191 if (rstate.avp) 1192 rc_avpair_insert(&send, NULL, rc_avpair_copy(rstate.avp)); 1193 1194 if (rstate.acctserver) { 1195 result = rc_acct_using_server(rstate.acctserver, 1196 rstate.client_port, send); 1197 } else { 1198 result = rc_acct(rstate.client_port, send); 1199 } 1200 1201 if (result != OK_RC) { 1202 /* RADIUS server could be down so make this a warning */ 1203 syslog(LOG_WARNING, 1204 "Interim accounting failed for %s", rstate.user); 1205 } 1206 rc_avpair_free(send); 1207 1208 /* Schedule another one */ 1209 TIMEOUT(radius_acct_interim, NULL, rstate.acct_interim_interval); 1210 } 1211 1212 /********************************************************************** 1213 * %FUNCTION: radius_ip_up 1214 * %ARGUMENTS: 1215 * opaque -- ignored 1216 * arg -- ignored 1217 * %RETURNS: 1218 * Nothing 1219 * %DESCRIPTION: 1220 * Called when IPCP is up. We'll do a start-accounting record. 1221 ***********************************************************************/ 1222 static void 1223 radius_ip_up(void *opaque, int arg) 1224 { 1225 radius_acct_start(); 1226 } 1227 1228 /********************************************************************** 1229 * %FUNCTION: radius_ip_down 1230 * %ARGUMENTS: 1231 * opaque -- ignored 1232 * arg -- ignored 1233 * %RETURNS: 1234 * Nothing 1235 * %DESCRIPTION: 1236 * Called when IPCP is down. We'll do a stop-accounting record. 1237 ***********************************************************************/ 1238 static void 1239 radius_ip_down(void *opaque, int arg) 1240 { 1241 radius_acct_stop(); 1242 } 1243 1244 /********************************************************************** 1245 * %FUNCTION: radius_init 1246 * %ARGUMENTS: 1247 * msg -- buffer of size BUF_LEN for error message 1248 * %RETURNS: 1249 * negative on failure; non-negative on success 1250 * %DESCRIPTION: 1251 * Initializes radiusclient library 1252 ***********************************************************************/ 1253 static int 1254 radius_init(char *msg) 1255 { 1256 if (rstate.initialized) { 1257 return 0; 1258 } 1259 1260 if (config_file && *config_file) { 1261 strlcpy(rstate.config_file, config_file, MAXPATHLEN-1); 1262 } 1263 1264 rstate.initialized = 1; 1265 1266 if (rc_read_config(rstate.config_file) != 0) { 1267 slprintf(msg, BUF_LEN, "RADIUS: Can't read config file %s", 1268 rstate.config_file); 1269 return -1; 1270 } 1271 1272 if (rc_read_dictionary(rc_conf_str("dictionary")) != 0) { 1273 slprintf(msg, BUF_LEN, "RADIUS: Can't read dictionary file %s", 1274 rc_conf_str("dictionary")); 1275 return -1; 1276 } 1277 1278 if (rc_read_mapfile(rc_conf_str("mapfile")) != 0) { 1279 slprintf(msg, BUF_LEN, "RADIUS: Can't read map file %s", 1280 rc_conf_str("mapfile")); 1281 return -1; 1282 } 1283 1284 /* Add av pairs saved during option parsing */ 1285 while (avpopt) { 1286 struct avpopt *n = avpopt->next; 1287 1288 rc_avpair_parse(avpopt->vpstr, &rstate.avp); 1289 free(avpopt->vpstr); 1290 free(avpopt); 1291 avpopt = n; 1292 } 1293 return 0; 1294 } 1295 1296 /********************************************************************** 1297 * %FUNCTION: get_client_port 1298 * %ARGUMENTS: 1299 * ifname -- PPP interface name (e.g. "ppp7") 1300 * %RETURNS: 1301 * The NAS port number (e.g. 7) 1302 * %DESCRIPTION: 1303 * Extracts the port number from the interface name 1304 ***********************************************************************/ 1305 static int 1306 get_client_port(char *ifname) 1307 { 1308 int port; 1309 if (sscanf(ifname, "ppp%d", &port) == 1) { 1310 return port; 1311 } 1312 return rc_map2id(ifname); 1313 } 1314 1315 /********************************************************************** 1316 * %FUNCTION: radius_allowed_address 1317 * %ARGUMENTS: 1318 * addr -- IP address 1319 * %RETURNS: 1320 * 1 if we're allowed to use that IP address; 0 if not; -1 if we do 1321 * not know. 1322 ***********************************************************************/ 1323 static int 1324 radius_allowed_address(u_int32_t addr) 1325 { 1326 ipcp_options *wo = &ipcp_wantoptions[0]; 1327 1328 if (!rstate.choose_ip) { 1329 /* If RADIUS server said any address is OK, then fine... */ 1330 if (rstate.any_ip_addr_ok) { 1331 return 1; 1332 } 1333 1334 /* Sigh... if an address was supplied for remote host in pppd 1335 options, it has to match that. */ 1336 if (wo->hisaddr != 0 && wo->hisaddr == addr) { 1337 return 1; 1338 } 1339 1340 return 0; 1341 } 1342 if (addr == rstate.ip_addr) return 1; 1343 return 0; 1344 } 1345 1346 /* Useful for other plugins */ 1347 char *radius_logged_in_user(void) 1348 { 1349 return rstate.user; 1350 } 1351