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 * 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 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 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$ 27 * 28 */ 29 30 #include <stdint.h> 31 #include <sys/param.h> 32 33 #include <sys/socket.h> 34 #include <netinet/in_systm.h> 35 #include <netinet/in.h> 36 #include <netinet/ip.h> 37 #include <arpa/inet.h> 38 #include <sys/un.h> 39 #include <net/route.h> 40 41 #ifdef LOCALRAD 42 #include "radlib.h" 43 #include "radlib_vs.h" 44 #else 45 #include <radlib.h> 46 #include <radlib_vs.h> 47 #endif 48 49 #include <errno.h> 50 #ifndef NODES 51 #include <md5.h> 52 #endif 53 #include <stdarg.h> 54 #include <stdio.h> 55 #include <stdlib.h> 56 #include <string.h> 57 #include <sys/time.h> 58 #include <termios.h> 59 #include <unistd.h> 60 #include <netdb.h> 61 62 #include "layer.h" 63 #include "defs.h" 64 #include "log.h" 65 #include "descriptor.h" 66 #include "prompt.h" 67 #include "timer.h" 68 #include "fsm.h" 69 #include "iplist.h" 70 #include "slcompress.h" 71 #include "throughput.h" 72 #include "lqr.h" 73 #include "hdlc.h" 74 #include "mbuf.h" 75 #include "ncpaddr.h" 76 #include "ip.h" 77 #include "ipcp.h" 78 #include "ipv6cp.h" 79 #include "route.h" 80 #include "command.h" 81 #include "filter.h" 82 #include "lcp.h" 83 #include "ccp.h" 84 #include "link.h" 85 #include "mp.h" 86 #include "radius.h" 87 #include "auth.h" 88 #include "async.h" 89 #include "physical.h" 90 #include "chat.h" 91 #include "cbcp.h" 92 #include "chap.h" 93 #include "datalink.h" 94 #include "ncp.h" 95 #include "bundle.h" 96 #include "proto.h" 97 98 #ifndef NODES 99 struct mschap_response { 100 u_char ident; 101 u_char flags; 102 u_char lm_response[24]; 103 u_char nt_response[24]; 104 }; 105 106 struct mschap2_response { 107 u_char ident; 108 u_char flags; 109 u_char pchallenge[16]; 110 u_char reserved[8]; 111 u_char response[24]; 112 }; 113 114 #define AUTH_LEN 16 115 #define SALT_LEN 2 116 #endif 117 118 static const char * 119 radius_policyname(int policy) 120 { 121 switch(policy) { 122 case MPPE_POLICY_ALLOWED: 123 return "Allowed"; 124 case MPPE_POLICY_REQUIRED: 125 return "Required"; 126 } 127 return NumStr(policy, NULL, 0); 128 } 129 130 static const char * 131 radius_typesname(int types) 132 { 133 switch(types) { 134 case MPPE_TYPE_40BIT: 135 return "40 bit"; 136 case MPPE_TYPE_128BIT: 137 return "128 bit"; 138 case MPPE_TYPE_40BIT|MPPE_TYPE_128BIT: 139 return "40 or 128 bit"; 140 } 141 return NumStr(types, NULL, 0); 142 } 143 144 #ifndef NODES 145 static void 146 demangle(struct radius *r, const void *mangled, size_t mlen, 147 char **buf, size_t *len) 148 { 149 char R[AUTH_LEN]; /* variable names as per rfc2548 */ 150 const char *S; 151 u_char b[16]; 152 const u_char *A, *C; 153 MD5_CTX Context; 154 int Slen, i, Clen, Ppos; 155 u_char *P; 156 157 if (mlen % 16 != SALT_LEN) { 158 log_Printf(LogWARN, "Cannot interpret mangled data of length %ld\n", 159 (u_long)mlen); 160 *buf = NULL; 161 *len = 0; 162 return; 163 } 164 165 /* We need the RADIUS Request-Authenticator */ 166 if (rad_request_authenticator(r->cx.rad, R, sizeof R) != AUTH_LEN) { 167 log_Printf(LogWARN, "Cannot obtain the RADIUS request authenticator\n"); 168 *buf = NULL; 169 *len = 0; 170 return; 171 } 172 173 A = (const u_char *)mangled; /* Salt comes first */ 174 C = (const u_char *)mangled + SALT_LEN; /* Then the ciphertext */ 175 Clen = mlen - SALT_LEN; 176 S = rad_server_secret(r->cx.rad); /* We need the RADIUS secret */ 177 Slen = strlen(S); 178 P = alloca(Clen); /* We derive our plaintext */ 179 180 MD5Init(&Context); 181 MD5Update(&Context, S, Slen); 182 MD5Update(&Context, R, AUTH_LEN); 183 MD5Update(&Context, A, SALT_LEN); 184 MD5Final(b, &Context); 185 Ppos = 0; 186 187 while (Clen) { 188 Clen -= 16; 189 190 for (i = 0; i < 16; i++) 191 P[Ppos++] = C[i] ^ b[i]; 192 193 if (Clen) { 194 MD5Init(&Context); 195 MD5Update(&Context, S, Slen); 196 MD5Update(&Context, C, 16); 197 MD5Final(b, &Context); 198 } 199 200 C += 16; 201 } 202 203 /* 204 * The resulting plain text consists of a one-byte length, the text and 205 * maybe some padding. 206 */ 207 *len = *P; 208 if (*len > mlen - 1) { 209 log_Printf(LogWARN, "Mangled data seems to be garbage\n"); 210 *buf = NULL; 211 *len = 0; 212 return; 213 } 214 215 *buf = malloc(*len); 216 memcpy(*buf, P + 1, *len); 217 } 218 #endif 219 220 /* XXX: This should go into librarius. */ 221 #ifndef NOINET6 222 static uint8_t * 223 rad_cvt_ipv6prefix(const void *data, size_t len) 224 { 225 const size_t ipv6len = sizeof(struct in6_addr) + 2; 226 uint8_t *s; 227 228 if (len > ipv6len) 229 return NULL; 230 s = malloc(ipv6len); 231 if (s != NULL) { 232 memset(s, 0, ipv6len); 233 memcpy(s, data, len); 234 } 235 return s; 236 } 237 #endif 238 239 /* 240 * rad_continue_send_request() has given us `got' (non-zero). Deal with it. 241 */ 242 static void 243 radius_Process(struct radius *r, int got) 244 { 245 char *argv[MAXARGS], *nuke; 246 struct bundle *bundle; 247 int argc, addrs, res, width; 248 size_t len; 249 struct ncprange dest; 250 struct ncpaddr gw; 251 const void *data; 252 const char *stype; 253 u_int32_t ipaddr, vendor; 254 struct in_addr ip; 255 #ifndef NOINET6 256 uint8_t ipv6addr[INET6_ADDRSTRLEN]; 257 struct in6_addr ip6; 258 #endif 259 260 r->cx.fd = -1; /* Stop select()ing */ 261 stype = r->cx.auth ? "auth" : "acct"; 262 263 switch (got) { 264 case RAD_ACCESS_ACCEPT: 265 log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE, 266 "Radius(%s): ACCEPT received\n", stype); 267 if (!r->cx.auth) { 268 rad_close(r->cx.rad); 269 return; 270 } 271 break; 272 273 case RAD_ACCESS_REJECT: 274 log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE, 275 "Radius(%s): REJECT received\n", stype); 276 if (!r->cx.auth) { 277 rad_close(r->cx.rad); 278 return; 279 } 280 break; 281 282 case RAD_ACCESS_CHALLENGE: 283 /* we can't deal with this (for now) ! */ 284 log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE, 285 "Radius: CHALLENGE received (can't handle yet)\n"); 286 if (r->cx.auth) 287 auth_Failure(r->cx.auth); 288 rad_close(r->cx.rad); 289 return; 290 291 case RAD_ACCOUNTING_RESPONSE: 292 /* 293 * It's probably not ideal to log this at PHASE level as we'll see 294 * too much stuff going to the log when ``set rad_alive'' is used. 295 * So we differ from older behaviour (ppp version 3.1 and before) 296 * and just log accounting responses to LogRADIUS. 297 */ 298 log_Printf(LogRADIUS, "Radius(%s): Accounting response received\n", 299 stype); 300 if (r->cx.auth) 301 auth_Failure(r->cx.auth); /* unexpected !!! */ 302 303 /* No further processing for accounting requests, please */ 304 rad_close(r->cx.rad); 305 return; 306 307 case -1: 308 log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE, 309 "radius(%s): %s\n", stype, rad_strerror(r->cx.rad)); 310 if (r->cx.auth) 311 auth_Failure(r->cx.auth); 312 rad_close(r->cx.rad); 313 return; 314 315 default: 316 log_Printf(LogERROR, "rad_send_request(%s): Failed %d: %s\n", stype, 317 got, rad_strerror(r->cx.rad)); 318 if (r->cx.auth) 319 auth_Failure(r->cx.auth); 320 rad_close(r->cx.rad); 321 return; 322 } 323 324 /* Let's see what we've got in our reply */ 325 r->ip.s_addr = r->mask.s_addr = INADDR_NONE; 326 r->mtu = 0; 327 r->vj = 0; 328 while ((res = rad_get_attr(r->cx.rad, &data, &len)) > 0) { 329 switch (res) { 330 case RAD_FRAMED_IP_ADDRESS: 331 r->ip = rad_cvt_addr(data); 332 log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE, 333 " IP %s\n", inet_ntoa(r->ip)); 334 break; 335 336 case RAD_FILTER_ID: 337 free(r->filterid); 338 if ((r->filterid = rad_cvt_string(data, len)) == NULL) { 339 log_Printf(LogERROR, "rad_cvt_string: %s\n", rad_strerror(r->cx.rad)); 340 auth_Failure(r->cx.auth); 341 rad_close(r->cx.rad); 342 return; 343 } 344 log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE, 345 " Filter \"%s\"\n", r->filterid); 346 break; 347 348 case RAD_SESSION_TIMEOUT: 349 r->sessiontime = rad_cvt_int(data); 350 log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE, 351 " Session-Timeout %lu\n", r->sessiontime); 352 break; 353 354 case RAD_FRAMED_IP_NETMASK: 355 r->mask = rad_cvt_addr(data); 356 log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE, 357 " Netmask %s\n", inet_ntoa(r->mask)); 358 break; 359 360 case RAD_FRAMED_MTU: 361 r->mtu = rad_cvt_int(data); 362 log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE, 363 " MTU %lu\n", r->mtu); 364 break; 365 366 case RAD_FRAMED_ROUTING: 367 /* Disabled for now - should we automatically set up some filters ? */ 368 /* rad_cvt_int(data); */ 369 /* bit 1 = Send routing packets */ 370 /* bit 2 = Receive routing packets */ 371 break; 372 373 case RAD_FRAMED_COMPRESSION: 374 r->vj = rad_cvt_int(data) == 1 ? 1 : 0; 375 log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE, 376 " VJ %sabled\n", r->vj ? "en" : "dis"); 377 break; 378 379 case RAD_FRAMED_ROUTE: 380 /* 381 * We expect a string of the format ``dest[/bits] gw [metrics]'' 382 * Any specified metrics are ignored. MYADDR and HISADDR are 383 * understood for ``dest'' and ``gw'' and ``0.0.0.0'' is the same 384 * as ``HISADDR''. 385 */ 386 387 if ((nuke = rad_cvt_string(data, len)) == NULL) { 388 log_Printf(LogERROR, "rad_cvt_string: %s\n", rad_strerror(r->cx.rad)); 389 auth_Failure(r->cx.auth); 390 rad_close(r->cx.rad); 391 return; 392 } 393 394 log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE, 395 " Route: %s\n", nuke); 396 bundle = r->cx.auth->physical->dl->bundle; 397 ip.s_addr = INADDR_ANY; 398 ncpaddr_setip4(&gw, ip); 399 ncprange_setip4host(&dest, ip); 400 argc = command_Interpret(nuke, strlen(nuke), argv); 401 if (argc < 0) 402 log_Printf(LogWARN, "radius: %s: Syntax error\n", 403 argc == 1 ? argv[0] : "\"\""); 404 else if (argc < 2) 405 log_Printf(LogWARN, "radius: %s: Invalid route\n", 406 argc == 1 ? argv[0] : "\"\""); 407 else if ((strcasecmp(argv[0], "default") != 0 && 408 !ncprange_aton(&dest, &bundle->ncp, argv[0])) || 409 !ncpaddr_aton(&gw, &bundle->ncp, argv[1])) 410 log_Printf(LogWARN, "radius: %s %s: Invalid route\n", 411 argv[0], argv[1]); 412 else { 413 ncprange_getwidth(&dest, &width); 414 if (width == 32 && strchr(argv[0], '/') == NULL) { 415 /* No mask specified - use the natural mask */ 416 ncprange_getip4addr(&dest, &ip); 417 ncprange_setip4mask(&dest, addr2mask(ip)); 418 } 419 addrs = 0; 420 421 if (!strncasecmp(argv[0], "HISADDR", 7)) 422 addrs = ROUTE_DSTHISADDR; 423 else if (!strncasecmp(argv[0], "MYADDR", 6)) 424 addrs = ROUTE_DSTMYADDR; 425 426 if (ncpaddr_getip4addr(&gw, &ipaddr) && ipaddr == INADDR_ANY) { 427 addrs |= ROUTE_GWHISADDR; 428 ncpaddr_setip4(&gw, bundle->ncp.ipcp.peer_ip); 429 } else if (strcasecmp(argv[1], "HISADDR") == 0) 430 addrs |= ROUTE_GWHISADDR; 431 432 route_Add(&r->routes, addrs, &dest, &gw); 433 } 434 free(nuke); 435 break; 436 437 case RAD_REPLY_MESSAGE: 438 free(r->repstr); 439 if ((r->repstr = rad_cvt_string(data, len)) == NULL) { 440 log_Printf(LogERROR, "rad_cvt_string: %s\n", rad_strerror(r->cx.rad)); 441 auth_Failure(r->cx.auth); 442 rad_close(r->cx.rad); 443 return; 444 } 445 log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE, 446 " Reply-Message \"%s\"\n", r->repstr); 447 break; 448 449 #ifndef NOINET6 450 case RAD_FRAMED_IPV6_PREFIX: 451 free(r->ipv6prefix); 452 r->ipv6prefix = rad_cvt_ipv6prefix(data, len); 453 inet_ntop(AF_INET6, &r->ipv6prefix[2], ipv6addr, sizeof(ipv6addr)); 454 log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE, 455 " IPv6 %s/%d\n", ipv6addr, r->ipv6prefix[1]); 456 break; 457 458 case RAD_FRAMED_IPV6_ROUTE: 459 /* 460 * We expect a string of the format ``dest[/bits] gw [metrics]'' 461 * Any specified metrics are ignored. MYADDR6 and HISADDR6 are 462 * understood for ``dest'' and ``gw'' and ``::'' is the same 463 * as ``HISADDR6''. 464 */ 465 466 if ((nuke = rad_cvt_string(data, len)) == NULL) { 467 log_Printf(LogERROR, "rad_cvt_string: %s\n", rad_strerror(r->cx.rad)); 468 auth_Failure(r->cx.auth); 469 rad_close(r->cx.rad); 470 return; 471 } 472 473 log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE, 474 " IPv6 Route: %s\n", nuke); 475 bundle = r->cx.auth->physical->dl->bundle; 476 ncpaddr_setip6(&gw, &in6addr_any); 477 ncprange_set(&dest, &gw, 0); 478 argc = command_Interpret(nuke, strlen(nuke), argv); 479 if (argc < 0) 480 log_Printf(LogWARN, "radius: %s: Syntax error\n", 481 argc == 1 ? argv[0] : "\"\""); 482 else if (argc < 2) 483 log_Printf(LogWARN, "radius: %s: Invalid route\n", 484 argc == 1 ? argv[0] : "\"\""); 485 else if ((strcasecmp(argv[0], "default") != 0 && 486 !ncprange_aton(&dest, &bundle->ncp, argv[0])) || 487 !ncpaddr_aton(&gw, &bundle->ncp, argv[1])) 488 log_Printf(LogWARN, "radius: %s %s: Invalid route\n", 489 argv[0], argv[1]); 490 else { 491 addrs = 0; 492 493 if (!strncasecmp(argv[0], "HISADDR6", 8)) 494 addrs = ROUTE_DSTHISADDR6; 495 else if (!strncasecmp(argv[0], "MYADDR6", 7)) 496 addrs = ROUTE_DSTMYADDR6; 497 498 if (ncpaddr_getip6(&gw, &ip6) && IN6_IS_ADDR_UNSPECIFIED(&ip6)) { 499 addrs |= ROUTE_GWHISADDR6; 500 ncpaddr_copy(&gw, &bundle->ncp.ipv6cp.hisaddr); 501 } else if (strcasecmp(argv[1], "HISADDR6") == 0) 502 addrs |= ROUTE_GWHISADDR6; 503 504 route_Add(&r->ipv6routes, addrs, &dest, &gw); 505 } 506 free(nuke); 507 break; 508 #endif 509 510 case RAD_VENDOR_SPECIFIC: 511 if ((res = rad_get_vendor_attr(&vendor, &data, &len)) <= 0) { 512 log_Printf(LogERROR, "rad_get_vendor_attr: %s (failing!)\n", 513 rad_strerror(r->cx.rad)); 514 auth_Failure(r->cx.auth); 515 rad_close(r->cx.rad); 516 return; 517 } 518 519 switch (vendor) { 520 case RAD_VENDOR_MICROSOFT: 521 switch (res) { 522 #ifndef NODES 523 case RAD_MICROSOFT_MS_CHAP_ERROR: 524 free(r->errstr); 525 if (len == 0) 526 r->errstr = NULL; 527 else { 528 if (len < 3 || ((const char *)data)[1] != '=') { 529 /* 530 * Only point at the String field if we don't think the 531 * peer has misformatted the response. 532 */ 533 data = (const char *)data + 1; 534 len--; 535 } else 536 log_Printf(LogWARN, "Warning: The MS-CHAP-Error " 537 "attribute is mis-formatted. Compensating\n"); 538 if ((r->errstr = rad_cvt_string((const char *)data, 539 len)) == NULL) { 540 log_Printf(LogERROR, "rad_cvt_string: %s\n", 541 rad_strerror(r->cx.rad)); 542 auth_Failure(r->cx.auth); 543 rad_close(r->cx.rad); 544 return; 545 } 546 log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE, 547 " MS-CHAP-Error \"%s\"\n", r->errstr); 548 } 549 break; 550 551 case RAD_MICROSOFT_MS_CHAP2_SUCCESS: 552 free(r->msrepstr); 553 if (len == 0) 554 r->msrepstr = NULL; 555 else { 556 if (len < 3 || ((const char *)data)[1] != '=') { 557 /* 558 * Only point at the String field if we don't think the 559 * peer has misformatted the response. 560 */ 561 data = (const char *)data + 1; 562 len--; 563 } else 564 log_Printf(LogWARN, "Warning: The MS-CHAP2-Success " 565 "attribute is mis-formatted. Compensating\n"); 566 if ((r->msrepstr = rad_cvt_string((const char *)data, 567 len)) == NULL) { 568 log_Printf(LogERROR, "rad_cvt_string: %s\n", 569 rad_strerror(r->cx.rad)); 570 auth_Failure(r->cx.auth); 571 rad_close(r->cx.rad); 572 return; 573 } 574 log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE, 575 " MS-CHAP2-Success \"%s\"\n", r->msrepstr); 576 } 577 break; 578 579 case RAD_MICROSOFT_MS_MPPE_ENCRYPTION_POLICY: 580 r->mppe.policy = rad_cvt_int(data); 581 log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE, 582 " MS-MPPE-Encryption-Policy %s\n", 583 radius_policyname(r->mppe.policy)); 584 break; 585 586 case RAD_MICROSOFT_MS_MPPE_ENCRYPTION_TYPES: 587 r->mppe.types = rad_cvt_int(data); 588 log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE, 589 " MS-MPPE-Encryption-Types %s\n", 590 radius_typesname(r->mppe.types)); 591 break; 592 593 case RAD_MICROSOFT_MS_MPPE_RECV_KEY: 594 free(r->mppe.recvkey); 595 demangle(r, data, len, &r->mppe.recvkey, &r->mppe.recvkeylen); 596 log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE, 597 " MS-MPPE-Recv-Key ********\n"); 598 break; 599 600 case RAD_MICROSOFT_MS_MPPE_SEND_KEY: 601 demangle(r, data, len, &r->mppe.sendkey, &r->mppe.sendkeylen); 602 log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE, 603 " MS-MPPE-Send-Key ********\n"); 604 break; 605 #endif 606 607 default: 608 log_Printf(LogDEBUG, "Dropping MICROSOFT vendor specific " 609 "RADIUS attribute %d\n", res); 610 break; 611 } 612 break; 613 614 default: 615 log_Printf(LogDEBUG, "Dropping vendor %lu RADIUS attribute %d\n", 616 (unsigned long)vendor, res); 617 break; 618 } 619 break; 620 621 default: 622 log_Printf(LogDEBUG, "Dropping RADIUS attribute %d\n", res); 623 break; 624 } 625 } 626 627 if (res == -1) { 628 log_Printf(LogERROR, "rad_get_attr: %s (failing!)\n", 629 rad_strerror(r->cx.rad)); 630 auth_Failure(r->cx.auth); 631 } else if (got == RAD_ACCESS_REJECT) 632 auth_Failure(r->cx.auth); 633 else { 634 r->valid = 1; 635 auth_Success(r->cx.auth); 636 } 637 rad_close(r->cx.rad); 638 } 639 640 /* 641 * We've either timed out or select()ed on the read descriptor 642 */ 643 static void 644 radius_Continue(struct radius *r, int sel) 645 { 646 struct timeval tv; 647 int got; 648 649 timer_Stop(&r->cx.timer); 650 if ((got = rad_continue_send_request(r->cx.rad, sel, &r->cx.fd, &tv)) == 0) { 651 log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE, 652 "Radius: Request re-sent\n"); 653 r->cx.timer.load = tv.tv_usec / TICKUNIT + tv.tv_sec * SECTICKS; 654 timer_Start(&r->cx.timer); 655 return; 656 } 657 658 radius_Process(r, got); 659 } 660 661 /* 662 * Time to call rad_continue_send_request() - timed out. 663 */ 664 static void 665 radius_Timeout(void *v) 666 { 667 radius_Continue((struct radius *)v, 0); 668 } 669 670 /* 671 * Time to call rad_continue_send_request() - something to read. 672 */ 673 static void 674 radius_Read(struct fdescriptor *d, struct bundle *bundle __unused, 675 const fd_set *fdset __unused) 676 { 677 radius_Continue(descriptor2radius(d), 1); 678 } 679 680 /* 681 * Behave as a struct fdescriptor (descriptor.h) 682 */ 683 static int 684 radius_UpdateSet(struct fdescriptor *d, fd_set *r, fd_set *w __unused, 685 fd_set *e __unused, int *n) 686 { 687 struct radius *rad = descriptor2radius(d); 688 689 if (r && rad->cx.fd != -1) { 690 FD_SET(rad->cx.fd, r); 691 if (*n < rad->cx.fd + 1) 692 *n = rad->cx.fd + 1; 693 log_Printf(LogTIMER, "Radius: fdset(r) %d\n", rad->cx.fd); 694 return 1; 695 } 696 697 return 0; 698 } 699 700 /* 701 * Behave as a struct fdescriptor (descriptor.h) 702 */ 703 static int 704 radius_IsSet(struct fdescriptor *d, const fd_set *fdset) 705 { 706 struct radius *r = descriptor2radius(d); 707 708 return r && r->cx.fd != -1 && FD_ISSET(r->cx.fd, fdset); 709 } 710 711 /* 712 * Behave as a struct fdescriptor (descriptor.h) 713 */ 714 static int 715 radius_Write(struct fdescriptor *d __unused, struct bundle *bundle __unused, 716 const fd_set *fdset __unused) 717 { 718 /* We never want to write here ! */ 719 log_Printf(LogALERT, "radius_Write: Internal error: Bad call !\n"); 720 return 0; 721 } 722 723 /* 724 * Initialise ourselves 725 */ 726 void 727 radius_Init(struct radius *r) 728 { 729 r->desc.type = RADIUS_DESCRIPTOR; 730 r->desc.UpdateSet = radius_UpdateSet; 731 r->desc.IsSet = radius_IsSet; 732 r->desc.Read = radius_Read; 733 r->desc.Write = radius_Write; 734 r->cx.fd = -1; 735 r->cx.rad = NULL; 736 memset(&r->cx.timer, '\0', sizeof r->cx.timer); 737 r->cx.auth = NULL; 738 r->valid = 0; 739 r->vj = 0; 740 r->ip.s_addr = INADDR_ANY; 741 r->mask.s_addr = INADDR_NONE; 742 r->routes = NULL; 743 r->mtu = DEF_MTU; 744 r->msrepstr = NULL; 745 r->repstr = NULL; 746 #ifndef NOINET6 747 r->ipv6prefix = NULL; 748 r->ipv6routes = NULL; 749 #endif 750 r->errstr = NULL; 751 r->mppe.policy = 0; 752 r->mppe.types = 0; 753 r->mppe.recvkey = NULL; 754 r->mppe.recvkeylen = 0; 755 r->mppe.sendkey = NULL; 756 r->mppe.sendkeylen = 0; 757 *r->cfg.file = '\0';; 758 log_Printf(LogDEBUG, "Radius: radius_Init\n"); 759 } 760 761 /* 762 * Forget everything and go back to initialised state. 763 */ 764 void 765 radius_Destroy(struct radius *r) 766 { 767 r->valid = 0; 768 log_Printf(LogDEBUG, "Radius: radius_Destroy\n"); 769 timer_Stop(&r->cx.timer); 770 route_DeleteAll(&r->routes); 771 #ifndef NOINET6 772 route_DeleteAll(&r->ipv6routes); 773 #endif 774 free(r->filterid); 775 r->filterid = NULL; 776 free(r->msrepstr); 777 r->msrepstr = NULL; 778 free(r->repstr); 779 r->repstr = NULL; 780 #ifndef NOINET6 781 free(r->ipv6prefix); 782 r->ipv6prefix = NULL; 783 #endif 784 free(r->errstr); 785 r->errstr = NULL; 786 free(r->mppe.recvkey); 787 r->mppe.recvkey = NULL; 788 r->mppe.recvkeylen = 0; 789 free(r->mppe.sendkey); 790 r->mppe.sendkey = NULL; 791 r->mppe.sendkeylen = 0; 792 if (r->cx.fd != -1) { 793 r->cx.fd = -1; 794 rad_close(r->cx.rad); 795 } 796 } 797 798 static int 799 radius_put_physical_details(struct rad_handle *rad, struct physical *p) 800 { 801 int slot, type; 802 803 type = RAD_VIRTUAL; 804 if (p->handler) 805 switch (p->handler->type) { 806 case I4B_DEVICE: 807 type = RAD_ISDN_SYNC; 808 break; 809 810 case TTY_DEVICE: 811 type = RAD_ASYNC; 812 break; 813 814 case ETHER_DEVICE: 815 type = RAD_ETHERNET; 816 break; 817 818 case TCP_DEVICE: 819 case UDP_DEVICE: 820 case EXEC_DEVICE: 821 case ATM_DEVICE: 822 case NG_DEVICE: 823 type = RAD_VIRTUAL; 824 break; 825 } 826 827 if (rad_put_int(rad, RAD_NAS_PORT_TYPE, type) != 0) { 828 log_Printf(LogERROR, "rad_put: rad_put_int: %s\n", rad_strerror(rad)); 829 rad_close(rad); 830 return 0; 831 } 832 833 if ((slot = physical_Slot(p)) >= 0) 834 if (rad_put_int(rad, RAD_NAS_PORT, slot) != 0) { 835 log_Printf(LogERROR, "rad_put: rad_put_int: %s\n", rad_strerror(rad)); 836 rad_close(rad); 837 return 0; 838 } 839 840 return 1; 841 } 842 843 /* 844 * Start an authentication request to the RADIUS server. 845 */ 846 int 847 radius_Authenticate(struct radius *r, struct authinfo *authp, const char *name, 848 const char *key, int klen, const char *nchallenge, 849 int nclen) 850 { 851 char hostname[MAXHOSTNAMELEN]; 852 struct timeval tv; 853 const char *what = "questionable"; /* silence warnings! */ 854 char *mac_addr; 855 int got; 856 #if 0 857 struct hostent *hp; 858 struct in_addr hostaddr; 859 #endif 860 #ifndef NODES 861 struct mschap_response msresp; 862 struct mschap2_response msresp2; 863 const struct MSCHAPv2_resp *keyv2; 864 #endif 865 866 if (!*r->cfg.file) 867 return 0; 868 869 if (r->cx.fd != -1) 870 /* 871 * We assume that our name/key/challenge is the same as last time, 872 * and just continue to wait for the RADIUS server(s). 873 */ 874 return 1; 875 876 radius_Destroy(r); 877 878 if ((r->cx.rad = rad_auth_open()) == NULL) { 879 log_Printf(LogERROR, "rad_auth_open: %s\n", strerror(errno)); 880 return 0; 881 } 882 883 if (rad_config(r->cx.rad, r->cfg.file) != 0) { 884 log_Printf(LogERROR, "rad_config: %s\n", rad_strerror(r->cx.rad)); 885 rad_close(r->cx.rad); 886 return 0; 887 } 888 889 if (rad_create_request(r->cx.rad, RAD_ACCESS_REQUEST) != 0) { 890 log_Printf(LogERROR, "rad_create_request: %s\n", rad_strerror(r->cx.rad)); 891 rad_close(r->cx.rad); 892 return 0; 893 } 894 895 if (rad_put_string(r->cx.rad, RAD_USER_NAME, name) != 0 || 896 rad_put_int(r->cx.rad, RAD_SERVICE_TYPE, RAD_FRAMED) != 0 || 897 rad_put_int(r->cx.rad, RAD_FRAMED_PROTOCOL, RAD_PPP) != 0) { 898 log_Printf(LogERROR, "rad_put: %s\n", rad_strerror(r->cx.rad)); 899 rad_close(r->cx.rad); 900 return 0; 901 } 902 903 switch (authp->physical->link.lcp.want_auth) { 904 case PROTO_PAP: 905 /* We're talking PAP */ 906 if (rad_put_attr(r->cx.rad, RAD_USER_PASSWORD, key, klen) != 0) { 907 log_Printf(LogERROR, "PAP: rad_put_string: %s\n", 908 rad_strerror(r->cx.rad)); 909 rad_close(r->cx.rad); 910 return 0; 911 } 912 what = "PAP"; 913 break; 914 915 case PROTO_CHAP: 916 switch (authp->physical->link.lcp.want_authtype) { 917 case 0x5: 918 if (rad_put_attr(r->cx.rad, RAD_CHAP_PASSWORD, key, klen) != 0 || 919 rad_put_attr(r->cx.rad, RAD_CHAP_CHALLENGE, nchallenge, nclen) != 0) { 920 log_Printf(LogERROR, "CHAP: rad_put_string: %s\n", 921 rad_strerror(r->cx.rad)); 922 rad_close(r->cx.rad); 923 return 0; 924 } 925 what = "CHAP"; 926 break; 927 928 #ifndef NODES 929 case 0x80: 930 if (klen != 50) { 931 log_Printf(LogERROR, "CHAP80: Unrecognised key length %d\n", klen); 932 rad_close(r->cx.rad); 933 return 0; 934 } 935 936 rad_put_vendor_attr(r->cx.rad, RAD_VENDOR_MICROSOFT, 937 RAD_MICROSOFT_MS_CHAP_CHALLENGE, nchallenge, nclen); 938 msresp.ident = *key; 939 msresp.flags = 0x01; 940 memcpy(msresp.lm_response, key + 1, 24); 941 memcpy(msresp.nt_response, key + 25, 24); 942 rad_put_vendor_attr(r->cx.rad, RAD_VENDOR_MICROSOFT, 943 RAD_MICROSOFT_MS_CHAP_RESPONSE, &msresp, 944 sizeof msresp); 945 what = "MSCHAP"; 946 break; 947 948 case 0x81: 949 if (klen != sizeof(*keyv2) + 1) { 950 log_Printf(LogERROR, "CHAP81: Unrecognised key length %d\n", klen); 951 rad_close(r->cx.rad); 952 return 0; 953 } 954 955 keyv2 = (const struct MSCHAPv2_resp *)(key + 1); 956 rad_put_vendor_attr(r->cx.rad, RAD_VENDOR_MICROSOFT, 957 RAD_MICROSOFT_MS_CHAP_CHALLENGE, nchallenge, nclen); 958 msresp2.ident = *key; 959 msresp2.flags = keyv2->Flags; 960 memcpy(msresp2.response, keyv2->NTResponse, sizeof msresp2.response); 961 memset(msresp2.reserved, '\0', sizeof msresp2.reserved); 962 memcpy(msresp2.pchallenge, keyv2->PeerChallenge, 963 sizeof msresp2.pchallenge); 964 rad_put_vendor_attr(r->cx.rad, RAD_VENDOR_MICROSOFT, 965 RAD_MICROSOFT_MS_CHAP2_RESPONSE, &msresp2, 966 sizeof msresp2); 967 what = "MSCHAPv2"; 968 break; 969 #endif 970 default: 971 log_Printf(LogERROR, "CHAP: Unrecognised type 0x%02x\n", 972 authp->physical->link.lcp.want_authtype); 973 rad_close(r->cx.rad); 974 return 0; 975 } 976 } 977 978 if (gethostname(hostname, sizeof hostname) != 0) 979 log_Printf(LogERROR, "rad_put: gethostname(): %s\n", strerror(errno)); 980 else { 981 #if 0 982 if ((hp = gethostbyname(hostname)) != NULL) { 983 hostaddr.s_addr = *(u_long *)hp->h_addr; 984 if (rad_put_addr(r->cx.rad, RAD_NAS_IP_ADDRESS, hostaddr) != 0) { 985 log_Printf(LogERROR, "rad_put: rad_put_string: %s\n", 986 rad_strerror(r->cx.rad)); 987 rad_close(r->cx.rad); 988 return 0; 989 } 990 } 991 #endif 992 if (rad_put_string(r->cx.rad, RAD_NAS_IDENTIFIER, hostname) != 0) { 993 log_Printf(LogERROR, "rad_put: rad_put_string: %s\n", 994 rad_strerror(r->cx.rad)); 995 rad_close(r->cx.rad); 996 return 0; 997 } 998 } 999 1000 if ((mac_addr = getenv("HISMACADDR")) != NULL && 1001 rad_put_string(r->cx.rad, RAD_CALLING_STATION_ID, mac_addr) != 0) { 1002 log_Printf(LogERROR, "rad_put: %s\n", rad_strerror(r->cx.rad)); 1003 rad_close(r->cx.rad); 1004 return 0; 1005 } 1006 1007 radius_put_physical_details(r->cx.rad, authp->physical); 1008 1009 log_Printf(LogRADIUS, "Radius(auth): %s data sent for %s\n", what, name); 1010 1011 r->cx.auth = authp; 1012 if ((got = rad_init_send_request(r->cx.rad, &r->cx.fd, &tv))) 1013 radius_Process(r, got); 1014 else { 1015 log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE, 1016 "Radius: Request sent\n"); 1017 log_Printf(LogDEBUG, "Using radius_Timeout [%p]\n", radius_Timeout); 1018 r->cx.timer.load = tv.tv_usec / TICKUNIT + tv.tv_sec * SECTICKS; 1019 r->cx.timer.func = radius_Timeout; 1020 r->cx.timer.name = "radius auth"; 1021 r->cx.timer.arg = r; 1022 timer_Start(&r->cx.timer); 1023 } 1024 1025 return 1; 1026 } 1027 1028 /* Fetch IP, netmask from IPCP */ 1029 void 1030 radius_Account_Set_Ip(struct radacct *ac, struct in_addr *peer_ip, 1031 struct in_addr *netmask) 1032 { 1033 ac->proto = PROTO_IPCP; 1034 memcpy(&ac->peer.ip.addr, peer_ip, sizeof(ac->peer.ip.addr)); 1035 memcpy(&ac->peer.ip.mask, netmask, sizeof(ac->peer.ip.mask)); 1036 } 1037 1038 #ifndef NOINET6 1039 /* Fetch interface-id from IPV6CP */ 1040 void 1041 radius_Account_Set_Ipv6(struct radacct *ac, u_char *ifid) 1042 { 1043 ac->proto = PROTO_IPV6CP; 1044 memcpy(&ac->peer.ipv6.ifid, ifid, sizeof(ac->peer.ipv6.ifid)); 1045 } 1046 #endif 1047 1048 /* 1049 * Send an accounting request to the RADIUS server 1050 */ 1051 void 1052 radius_Account(struct radius *r, struct radacct *ac, struct datalink *dl, 1053 int acct_type, struct pppThroughput *stats) 1054 { 1055 struct timeval tv; 1056 int got; 1057 char hostname[MAXHOSTNAMELEN]; 1058 char *mac_addr; 1059 #if 0 1060 struct hostent *hp; 1061 struct in_addr hostaddr; 1062 #endif 1063 1064 if (!*r->cfg.file) 1065 return; 1066 1067 if (r->cx.fd != -1) 1068 /* 1069 * We assume that our name/key/challenge is the same as last time, 1070 * and just continue to wait for the RADIUS server(s). 1071 */ 1072 return; 1073 1074 timer_Stop(&r->cx.timer); 1075 1076 if ((r->cx.rad = rad_acct_open()) == NULL) { 1077 log_Printf(LogERROR, "rad_auth_open: %s\n", strerror(errno)); 1078 return; 1079 } 1080 1081 if (rad_config(r->cx.rad, r->cfg.file) != 0) { 1082 log_Printf(LogERROR, "rad_config: %s\n", rad_strerror(r->cx.rad)); 1083 rad_close(r->cx.rad); 1084 return; 1085 } 1086 1087 if (rad_create_request(r->cx.rad, RAD_ACCOUNTING_REQUEST) != 0) { 1088 log_Printf(LogERROR, "rad_create_request: %s\n", rad_strerror(r->cx.rad)); 1089 rad_close(r->cx.rad); 1090 return; 1091 } 1092 1093 /* Grab some accounting data and initialize structure */ 1094 if (acct_type == RAD_START) { 1095 ac->rad_parent = r; 1096 /* Fetch username from datalink */ 1097 strncpy(ac->user_name, dl->peer.authname, sizeof ac->user_name); 1098 ac->user_name[AUTHLEN-1] = '\0'; 1099 1100 ac->authentic = 2; /* Assume RADIUS verified auth data */ 1101 1102 /* Generate a session ID */ 1103 snprintf(ac->session_id, sizeof ac->session_id, "%s%ld-%s%lu", 1104 dl->bundle->cfg.auth.name, (long)getpid(), 1105 dl->peer.authname, (unsigned long)stats->uptime); 1106 1107 /* And grab our MP socket name */ 1108 snprintf(ac->multi_session_id, sizeof ac->multi_session_id, "%s", 1109 dl->bundle->ncp.mp.active ? 1110 dl->bundle->ncp.mp.server.socket.sun_path : ""); 1111 }; 1112 1113 if (rad_put_string(r->cx.rad, RAD_USER_NAME, ac->user_name) != 0 || 1114 rad_put_int(r->cx.rad, RAD_SERVICE_TYPE, RAD_FRAMED) != 0 || 1115 rad_put_int(r->cx.rad, RAD_FRAMED_PROTOCOL, RAD_PPP) != 0) { 1116 log_Printf(LogERROR, "rad_put: %s\n", rad_strerror(r->cx.rad)); 1117 rad_close(r->cx.rad); 1118 return; 1119 } 1120 switch (ac->proto) { 1121 case PROTO_IPCP: 1122 if (rad_put_addr(r->cx.rad, RAD_FRAMED_IP_ADDRESS, 1123 ac->peer.ip.addr) != 0 || 1124 rad_put_addr(r->cx.rad, RAD_FRAMED_IP_NETMASK, 1125 ac->peer.ip.mask) != 0) { 1126 log_Printf(LogERROR, "rad_put: %s\n", rad_strerror(r->cx.rad)); 1127 rad_close(r->cx.rad); 1128 return; 1129 } 1130 break; 1131 #ifndef NOINET6 1132 case PROTO_IPV6CP: 1133 if (rad_put_attr(r->cx.rad, RAD_FRAMED_INTERFACE_ID, ac->peer.ipv6.ifid, 1134 sizeof(ac->peer.ipv6.ifid)) != 0) { 1135 log_Printf(LogERROR, "rad_put_attr: %s\n", rad_strerror(r->cx.rad)); 1136 rad_close(r->cx.rad); 1137 return; 1138 } 1139 if (r->ipv6prefix) { 1140 /* 1141 * Since PPP doesn't delegate an IPv6 prefix to a peer, 1142 * Framed-IPv6-Prefix may be not used, actually. 1143 */ 1144 if (rad_put_attr(r->cx.rad, RAD_FRAMED_IPV6_PREFIX, r->ipv6prefix, 1145 sizeof(struct in6_addr) + 2) != 0) { 1146 log_Printf(LogERROR, "rad_put_attr: %s\n", rad_strerror(r->cx.rad)); 1147 rad_close(r->cx.rad); 1148 return; 1149 } 1150 } 1151 break; 1152 #endif 1153 default: 1154 /* We don't log any protocol specific information */ 1155 break; 1156 } 1157 1158 if ((mac_addr = getenv("HISMACADDR")) != NULL && 1159 rad_put_string(r->cx.rad, RAD_CALLING_STATION_ID, mac_addr) != 0) { 1160 log_Printf(LogERROR, "rad_put: %s\n", rad_strerror(r->cx.rad)); 1161 rad_close(r->cx.rad); 1162 return; 1163 } 1164 1165 if (gethostname(hostname, sizeof hostname) != 0) 1166 log_Printf(LogERROR, "rad_put: gethostname(): %s\n", strerror(errno)); 1167 else { 1168 #if 0 1169 if ((hp = gethostbyname(hostname)) != NULL) { 1170 hostaddr.s_addr = *(u_long *)hp->h_addr; 1171 if (rad_put_addr(r->cx.rad, RAD_NAS_IP_ADDRESS, hostaddr) != 0) { 1172 log_Printf(LogERROR, "rad_put: rad_put_string: %s\n", 1173 rad_strerror(r->cx.rad)); 1174 rad_close(r->cx.rad); 1175 return; 1176 } 1177 } 1178 #endif 1179 if (rad_put_string(r->cx.rad, RAD_NAS_IDENTIFIER, hostname) != 0) { 1180 log_Printf(LogERROR, "rad_put: rad_put_string: %s\n", 1181 rad_strerror(r->cx.rad)); 1182 rad_close(r->cx.rad); 1183 return; 1184 } 1185 } 1186 1187 radius_put_physical_details(r->cx.rad, dl->physical); 1188 1189 if (rad_put_int(r->cx.rad, RAD_ACCT_STATUS_TYPE, acct_type) != 0 || 1190 rad_put_string(r->cx.rad, RAD_ACCT_SESSION_ID, ac->session_id) != 0 || 1191 rad_put_string(r->cx.rad, RAD_ACCT_MULTI_SESSION_ID, 1192 ac->multi_session_id) != 0 || 1193 rad_put_int(r->cx.rad, RAD_ACCT_DELAY_TIME, 0) != 0) { 1194 /* XXX ACCT_DELAY_TIME should be increased each time a packet is waiting */ 1195 log_Printf(LogERROR, "rad_put: %s\n", rad_strerror(r->cx.rad)); 1196 rad_close(r->cx.rad); 1197 return; 1198 } 1199 1200 if (acct_type == RAD_STOP || acct_type == RAD_ALIVE) 1201 /* Show some statistics */ 1202 if (rad_put_int(r->cx.rad, RAD_ACCT_INPUT_OCTETS, stats->OctetsIn % UINT32_MAX) != 0 || 1203 rad_put_int(r->cx.rad, RAD_ACCT_INPUT_GIGAWORDS, stats->OctetsIn / UINT32_MAX) != 0 || 1204 rad_put_int(r->cx.rad, RAD_ACCT_INPUT_PACKETS, stats->PacketsIn) != 0 || 1205 rad_put_int(r->cx.rad, RAD_ACCT_OUTPUT_OCTETS, stats->OctetsOut % UINT32_MAX) != 0 || 1206 rad_put_int(r->cx.rad, RAD_ACCT_OUTPUT_GIGAWORDS, stats->OctetsOut / UINT32_MAX) != 0 || 1207 rad_put_int(r->cx.rad, RAD_ACCT_OUTPUT_PACKETS, stats->PacketsOut) 1208 != 0 || 1209 rad_put_int(r->cx.rad, RAD_ACCT_SESSION_TIME, throughput_uptime(stats)) 1210 != 0) { 1211 log_Printf(LogERROR, "rad_put: %s\n", rad_strerror(r->cx.rad)); 1212 rad_close(r->cx.rad); 1213 return; 1214 } 1215 1216 if (log_IsKept(LogPHASE) || log_IsKept(LogRADIUS)) { 1217 const char *what; 1218 int level; 1219 1220 switch (acct_type) { 1221 case RAD_START: 1222 what = "START"; 1223 level = log_IsKept(LogPHASE) ? LogPHASE : LogRADIUS; 1224 break; 1225 case RAD_STOP: 1226 what = "STOP"; 1227 level = log_IsKept(LogPHASE) ? LogPHASE : LogRADIUS; 1228 break; 1229 case RAD_ALIVE: 1230 what = "ALIVE"; 1231 level = LogRADIUS; 1232 break; 1233 default: 1234 what = "<unknown>"; 1235 level = log_IsKept(LogPHASE) ? LogPHASE : LogRADIUS; 1236 break; 1237 } 1238 log_Printf(level, "Radius(acct): %s data sent\n", what); 1239 } 1240 1241 r->cx.auth = NULL; /* Not valid for accounting requests */ 1242 if ((got = rad_init_send_request(r->cx.rad, &r->cx.fd, &tv))) 1243 radius_Process(r, got); 1244 else { 1245 log_Printf(LogDEBUG, "Using radius_Timeout [%p]\n", radius_Timeout); 1246 r->cx.timer.load = tv.tv_usec / TICKUNIT + tv.tv_sec * SECTICKS; 1247 r->cx.timer.func = radius_Timeout; 1248 r->cx.timer.name = "radius acct"; 1249 r->cx.timer.arg = r; 1250 timer_Start(&r->cx.timer); 1251 } 1252 } 1253 1254 /* 1255 * How do things look at the moment ? 1256 */ 1257 void 1258 radius_Show(struct radius *r, struct prompt *p) 1259 { 1260 prompt_Printf(p, " Radius config: %s", 1261 *r->cfg.file ? r->cfg.file : "none"); 1262 if (r->valid) { 1263 prompt_Printf(p, "\n IP: %s\n", inet_ntoa(r->ip)); 1264 prompt_Printf(p, " Netmask: %s\n", inet_ntoa(r->mask)); 1265 prompt_Printf(p, " MTU: %lu\n", r->mtu); 1266 prompt_Printf(p, " VJ: %sabled\n", r->vj ? "en" : "dis"); 1267 prompt_Printf(p, " Message: %s\n", r->repstr ? r->repstr : ""); 1268 prompt_Printf(p, " MPPE Enc Policy: %s\n", 1269 radius_policyname(r->mppe.policy)); 1270 prompt_Printf(p, " MPPE Enc Types: %s\n", 1271 radius_typesname(r->mppe.types)); 1272 prompt_Printf(p, " MPPE Recv Key: %seceived\n", 1273 r->mppe.recvkey ? "R" : "Not r"); 1274 prompt_Printf(p, " MPPE Send Key: %seceived\n", 1275 r->mppe.sendkey ? "R" : "Not r"); 1276 prompt_Printf(p, " MS-CHAP2-Response: %s\n", 1277 r->msrepstr ? r->msrepstr : ""); 1278 prompt_Printf(p, " Error Message: %s\n", r->errstr ? r->errstr : ""); 1279 if (r->routes) 1280 route_ShowSticky(p, r->routes, " Routes", 16); 1281 #ifndef NOINET6 1282 if (r->ipv6routes) 1283 route_ShowSticky(p, r->ipv6routes, " IPv6 Routes", 16); 1284 #endif 1285 } else 1286 prompt_Printf(p, " (not authenticated)\n"); 1287 } 1288 1289 static void 1290 radius_alive(void *v) 1291 { 1292 struct bundle *bundle = (struct bundle *)v; 1293 1294 timer_Stop(&bundle->radius.alive.timer); 1295 bundle->radius.alive.timer.load = bundle->radius.alive.interval * SECTICKS; 1296 if (bundle->radius.alive.timer.load) { 1297 radius_Account(&bundle->radius, &bundle->radacct, 1298 bundle->links, RAD_ALIVE, &bundle->ncp.ipcp.throughput); 1299 timer_Start(&bundle->radius.alive.timer); 1300 } 1301 } 1302 1303 void 1304 radius_StartTimer(struct bundle *bundle) 1305 { 1306 if (bundle->radius.cfg.file && bundle->radius.alive.interval) { 1307 bundle->radius.alive.timer.func = radius_alive; 1308 bundle->radius.alive.timer.name = "radius alive"; 1309 bundle->radius.alive.timer.load = bundle->radius.alive.interval * SECTICKS; 1310 bundle->radius.alive.timer.arg = bundle; 1311 radius_alive(bundle); 1312 } 1313 } 1314 1315 void 1316 radius_StopTimer(struct radius *r) 1317 { 1318 timer_Stop(&r->alive.timer); 1319 } 1320