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, const fd_set *fdset) 675 { 676 radius_Continue(descriptor2radius(d), 1); 677 } 678 679 /* 680 * Behave as a struct fdescriptor (descriptor.h) 681 */ 682 static int 683 radius_UpdateSet(struct fdescriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) 684 { 685 struct radius *rad = descriptor2radius(d); 686 687 if (r && rad->cx.fd != -1) { 688 FD_SET(rad->cx.fd, r); 689 if (*n < rad->cx.fd + 1) 690 *n = rad->cx.fd + 1; 691 log_Printf(LogTIMER, "Radius: fdset(r) %d\n", rad->cx.fd); 692 return 1; 693 } 694 695 return 0; 696 } 697 698 /* 699 * Behave as a struct fdescriptor (descriptor.h) 700 */ 701 static int 702 radius_IsSet(struct fdescriptor *d, const fd_set *fdset) 703 { 704 struct radius *r = descriptor2radius(d); 705 706 return r && r->cx.fd != -1 && FD_ISSET(r->cx.fd, fdset); 707 } 708 709 /* 710 * Behave as a struct fdescriptor (descriptor.h) 711 */ 712 static int 713 radius_Write(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset) 714 { 715 /* We never want to write here ! */ 716 log_Printf(LogALERT, "radius_Write: Internal error: Bad call !\n"); 717 return 0; 718 } 719 720 /* 721 * Initialise ourselves 722 */ 723 void 724 radius_Init(struct radius *r) 725 { 726 r->desc.type = RADIUS_DESCRIPTOR; 727 r->desc.UpdateSet = radius_UpdateSet; 728 r->desc.IsSet = radius_IsSet; 729 r->desc.Read = radius_Read; 730 r->desc.Write = radius_Write; 731 r->cx.fd = -1; 732 r->cx.rad = NULL; 733 memset(&r->cx.timer, '\0', sizeof r->cx.timer); 734 r->cx.auth = NULL; 735 r->valid = 0; 736 r->vj = 0; 737 r->ip.s_addr = INADDR_ANY; 738 r->mask.s_addr = INADDR_NONE; 739 r->routes = NULL; 740 r->mtu = DEF_MTU; 741 r->msrepstr = NULL; 742 r->repstr = NULL; 743 #ifndef NOINET6 744 r->ipv6prefix = NULL; 745 r->ipv6routes = NULL; 746 #endif 747 r->errstr = NULL; 748 r->mppe.policy = 0; 749 r->mppe.types = 0; 750 r->mppe.recvkey = NULL; 751 r->mppe.recvkeylen = 0; 752 r->mppe.sendkey = NULL; 753 r->mppe.sendkeylen = 0; 754 *r->cfg.file = '\0';; 755 log_Printf(LogDEBUG, "Radius: radius_Init\n"); 756 } 757 758 /* 759 * Forget everything and go back to initialised state. 760 */ 761 void 762 radius_Destroy(struct radius *r) 763 { 764 r->valid = 0; 765 log_Printf(LogDEBUG, "Radius: radius_Destroy\n"); 766 timer_Stop(&r->cx.timer); 767 route_DeleteAll(&r->routes); 768 #ifndef NOINET6 769 route_DeleteAll(&r->ipv6routes); 770 #endif 771 free(r->filterid); 772 r->filterid = NULL; 773 free(r->msrepstr); 774 r->msrepstr = NULL; 775 free(r->repstr); 776 r->repstr = NULL; 777 #ifndef NOINET6 778 free(r->ipv6prefix); 779 r->ipv6prefix = NULL; 780 #endif 781 free(r->errstr); 782 r->errstr = NULL; 783 free(r->mppe.recvkey); 784 r->mppe.recvkey = NULL; 785 r->mppe.recvkeylen = 0; 786 free(r->mppe.sendkey); 787 r->mppe.sendkey = NULL; 788 r->mppe.sendkeylen = 0; 789 if (r->cx.fd != -1) { 790 r->cx.fd = -1; 791 rad_close(r->cx.rad); 792 } 793 } 794 795 static int 796 radius_put_physical_details(struct rad_handle *rad, struct physical *p) 797 { 798 int slot, type; 799 800 type = RAD_VIRTUAL; 801 if (p->handler) 802 switch (p->handler->type) { 803 case I4B_DEVICE: 804 type = RAD_ISDN_SYNC; 805 break; 806 807 case TTY_DEVICE: 808 type = RAD_ASYNC; 809 break; 810 811 case ETHER_DEVICE: 812 type = RAD_ETHERNET; 813 break; 814 815 case TCP_DEVICE: 816 case UDP_DEVICE: 817 case EXEC_DEVICE: 818 case ATM_DEVICE: 819 case NG_DEVICE: 820 type = RAD_VIRTUAL; 821 break; 822 } 823 824 if (rad_put_int(rad, RAD_NAS_PORT_TYPE, type) != 0) { 825 log_Printf(LogERROR, "rad_put: rad_put_int: %s\n", rad_strerror(rad)); 826 rad_close(rad); 827 return 0; 828 } 829 830 if ((slot = physical_Slot(p)) >= 0) 831 if (rad_put_int(rad, RAD_NAS_PORT, slot) != 0) { 832 log_Printf(LogERROR, "rad_put: rad_put_int: %s\n", rad_strerror(rad)); 833 rad_close(rad); 834 return 0; 835 } 836 837 return 1; 838 } 839 840 /* 841 * Start an authentication request to the RADIUS server. 842 */ 843 int 844 radius_Authenticate(struct radius *r, struct authinfo *authp, const char *name, 845 const char *key, int klen, const char *nchallenge, 846 int nclen) 847 { 848 struct timeval tv; 849 int got; 850 char hostname[MAXHOSTNAMELEN]; 851 char *mac_addr, *what; 852 #if 0 853 struct hostent *hp; 854 struct in_addr hostaddr; 855 #endif 856 #ifndef NODES 857 struct mschap_response msresp; 858 struct mschap2_response msresp2; 859 const struct MSCHAPv2_resp *keyv2; 860 #endif 861 862 if (!*r->cfg.file) 863 return 0; 864 865 if (r->cx.fd != -1) 866 /* 867 * We assume that our name/key/challenge is the same as last time, 868 * and just continue to wait for the RADIUS server(s). 869 */ 870 return 1; 871 872 radius_Destroy(r); 873 874 if ((r->cx.rad = rad_auth_open()) == NULL) { 875 log_Printf(LogERROR, "rad_auth_open: %s\n", strerror(errno)); 876 return 0; 877 } 878 879 if (rad_config(r->cx.rad, r->cfg.file) != 0) { 880 log_Printf(LogERROR, "rad_config: %s\n", rad_strerror(r->cx.rad)); 881 rad_close(r->cx.rad); 882 return 0; 883 } 884 885 if (rad_create_request(r->cx.rad, RAD_ACCESS_REQUEST) != 0) { 886 log_Printf(LogERROR, "rad_create_request: %s\n", rad_strerror(r->cx.rad)); 887 rad_close(r->cx.rad); 888 return 0; 889 } 890 891 if (rad_put_string(r->cx.rad, RAD_USER_NAME, name) != 0 || 892 rad_put_int(r->cx.rad, RAD_SERVICE_TYPE, RAD_FRAMED) != 0 || 893 rad_put_int(r->cx.rad, RAD_FRAMED_PROTOCOL, RAD_PPP) != 0) { 894 log_Printf(LogERROR, "rad_put: %s\n", rad_strerror(r->cx.rad)); 895 rad_close(r->cx.rad); 896 return 0; 897 } 898 899 switch (authp->physical->link.lcp.want_auth) { 900 case PROTO_PAP: 901 /* We're talking PAP */ 902 if (rad_put_attr(r->cx.rad, RAD_USER_PASSWORD, key, klen) != 0) { 903 log_Printf(LogERROR, "PAP: rad_put_string: %s\n", 904 rad_strerror(r->cx.rad)); 905 rad_close(r->cx.rad); 906 return 0; 907 } 908 what = "PAP"; 909 break; 910 911 case PROTO_CHAP: 912 switch (authp->physical->link.lcp.want_authtype) { 913 case 0x5: 914 if (rad_put_attr(r->cx.rad, RAD_CHAP_PASSWORD, key, klen) != 0 || 915 rad_put_attr(r->cx.rad, RAD_CHAP_CHALLENGE, nchallenge, nclen) != 0) { 916 log_Printf(LogERROR, "CHAP: rad_put_string: %s\n", 917 rad_strerror(r->cx.rad)); 918 rad_close(r->cx.rad); 919 return 0; 920 } 921 what = "CHAP"; 922 break; 923 924 #ifndef NODES 925 case 0x80: 926 if (klen != 50) { 927 log_Printf(LogERROR, "CHAP80: Unrecognised key length %d\n", klen); 928 rad_close(r->cx.rad); 929 return 0; 930 } 931 932 rad_put_vendor_attr(r->cx.rad, RAD_VENDOR_MICROSOFT, 933 RAD_MICROSOFT_MS_CHAP_CHALLENGE, nchallenge, nclen); 934 msresp.ident = *key; 935 msresp.flags = 0x01; 936 memcpy(msresp.lm_response, key + 1, 24); 937 memcpy(msresp.nt_response, key + 25, 24); 938 rad_put_vendor_attr(r->cx.rad, RAD_VENDOR_MICROSOFT, 939 RAD_MICROSOFT_MS_CHAP_RESPONSE, &msresp, 940 sizeof msresp); 941 what = "MSCHAP"; 942 break; 943 944 case 0x81: 945 if (klen != sizeof(*keyv2) + 1) { 946 log_Printf(LogERROR, "CHAP81: Unrecognised key length %d\n", klen); 947 rad_close(r->cx.rad); 948 return 0; 949 } 950 951 keyv2 = (const struct MSCHAPv2_resp *)(key + 1); 952 rad_put_vendor_attr(r->cx.rad, RAD_VENDOR_MICROSOFT, 953 RAD_MICROSOFT_MS_CHAP_CHALLENGE, nchallenge, nclen); 954 msresp2.ident = *key; 955 msresp2.flags = keyv2->Flags; 956 memcpy(msresp2.response, keyv2->NTResponse, sizeof msresp2.response); 957 memset(msresp2.reserved, '\0', sizeof msresp2.reserved); 958 memcpy(msresp2.pchallenge, keyv2->PeerChallenge, 959 sizeof msresp2.pchallenge); 960 rad_put_vendor_attr(r->cx.rad, RAD_VENDOR_MICROSOFT, 961 RAD_MICROSOFT_MS_CHAP2_RESPONSE, &msresp2, 962 sizeof msresp2); 963 what = "MSCHAPv2"; 964 break; 965 #endif 966 default: 967 log_Printf(LogERROR, "CHAP: Unrecognised type 0x%02x\n", 968 authp->physical->link.lcp.want_authtype); 969 rad_close(r->cx.rad); 970 return 0; 971 } 972 } 973 974 if (gethostname(hostname, sizeof hostname) != 0) 975 log_Printf(LogERROR, "rad_put: gethostname(): %s\n", strerror(errno)); 976 else { 977 #if 0 978 if ((hp = gethostbyname(hostname)) != NULL) { 979 hostaddr.s_addr = *(u_long *)hp->h_addr; 980 if (rad_put_addr(r->cx.rad, RAD_NAS_IP_ADDRESS, hostaddr) != 0) { 981 log_Printf(LogERROR, "rad_put: rad_put_string: %s\n", 982 rad_strerror(r->cx.rad)); 983 rad_close(r->cx.rad); 984 return 0; 985 } 986 } 987 #endif 988 if (rad_put_string(r->cx.rad, RAD_NAS_IDENTIFIER, hostname) != 0) { 989 log_Printf(LogERROR, "rad_put: rad_put_string: %s\n", 990 rad_strerror(r->cx.rad)); 991 rad_close(r->cx.rad); 992 return 0; 993 } 994 } 995 996 if ((mac_addr = getenv("HISMACADDR")) != NULL && 997 rad_put_string(r->cx.rad, RAD_CALLING_STATION_ID, mac_addr) != 0) { 998 log_Printf(LogERROR, "rad_put: %s\n", rad_strerror(r->cx.rad)); 999 rad_close(r->cx.rad); 1000 return; 1001 } 1002 1003 radius_put_physical_details(r->cx.rad, authp->physical); 1004 1005 log_Printf(LogRADIUS, "Radius(auth): %s data sent for %s\n", what, name); 1006 1007 r->cx.auth = authp; 1008 if ((got = rad_init_send_request(r->cx.rad, &r->cx.fd, &tv))) 1009 radius_Process(r, got); 1010 else { 1011 log_Printf(log_IsKept(LogRADIUS) ? LogRADIUS : LogPHASE, 1012 "Radius: Request sent\n"); 1013 log_Printf(LogDEBUG, "Using radius_Timeout [%p]\n", radius_Timeout); 1014 r->cx.timer.load = tv.tv_usec / TICKUNIT + tv.tv_sec * SECTICKS; 1015 r->cx.timer.func = radius_Timeout; 1016 r->cx.timer.name = "radius auth"; 1017 r->cx.timer.arg = r; 1018 timer_Start(&r->cx.timer); 1019 } 1020 1021 return 1; 1022 } 1023 1024 /* Fetch IP, netmask from IPCP */ 1025 void 1026 radius_Account_Set_Ip(struct radacct *ac, struct in_addr *peer_ip, 1027 struct in_addr *netmask) 1028 { 1029 ac->proto = PROTO_IPCP; 1030 memcpy(&ac->peer.ip.addr, peer_ip, sizeof(ac->peer.ip.addr)); 1031 memcpy(&ac->peer.ip.mask, netmask, sizeof(ac->peer.ip.mask)); 1032 } 1033 1034 #ifndef NOINET6 1035 /* Fetch interface-id from IPV6CP */ 1036 void 1037 radius_Account_Set_Ipv6(struct radacct *ac, u_char *ifid) 1038 { 1039 ac->proto = PROTO_IPV6CP; 1040 memcpy(&ac->peer.ipv6.ifid, ifid, sizeof(ac->peer.ipv6.ifid)); 1041 } 1042 #endif 1043 1044 /* 1045 * Send an accounting request to the RADIUS server 1046 */ 1047 void 1048 radius_Account(struct radius *r, struct radacct *ac, struct datalink *dl, 1049 int acct_type, struct pppThroughput *stats) 1050 { 1051 struct timeval tv; 1052 int got; 1053 char hostname[MAXHOSTNAMELEN]; 1054 char *mac_addr; 1055 #if 0 1056 struct hostent *hp; 1057 struct in_addr hostaddr; 1058 #endif 1059 1060 if (!*r->cfg.file) 1061 return; 1062 1063 if (r->cx.fd != -1) 1064 /* 1065 * We assume that our name/key/challenge is the same as last time, 1066 * and just continue to wait for the RADIUS server(s). 1067 */ 1068 return; 1069 1070 timer_Stop(&r->cx.timer); 1071 1072 if ((r->cx.rad = rad_acct_open()) == NULL) { 1073 log_Printf(LogERROR, "rad_auth_open: %s\n", strerror(errno)); 1074 return; 1075 } 1076 1077 if (rad_config(r->cx.rad, r->cfg.file) != 0) { 1078 log_Printf(LogERROR, "rad_config: %s\n", rad_strerror(r->cx.rad)); 1079 rad_close(r->cx.rad); 1080 return; 1081 } 1082 1083 if (rad_create_request(r->cx.rad, RAD_ACCOUNTING_REQUEST) != 0) { 1084 log_Printf(LogERROR, "rad_create_request: %s\n", rad_strerror(r->cx.rad)); 1085 rad_close(r->cx.rad); 1086 return; 1087 } 1088 1089 /* Grab some accounting data and initialize structure */ 1090 if (acct_type == RAD_START) { 1091 ac->rad_parent = r; 1092 /* Fetch username from datalink */ 1093 strncpy(ac->user_name, dl->peer.authname, sizeof ac->user_name); 1094 ac->user_name[AUTHLEN-1] = '\0'; 1095 1096 ac->authentic = 2; /* Assume RADIUS verified auth data */ 1097 1098 /* Generate a session ID */ 1099 snprintf(ac->session_id, sizeof ac->session_id, "%s%ld-%s%lu", 1100 dl->bundle->cfg.auth.name, (long)getpid(), 1101 dl->peer.authname, (unsigned long)stats->uptime); 1102 1103 /* And grab our MP socket name */ 1104 snprintf(ac->multi_session_id, sizeof ac->multi_session_id, "%s", 1105 dl->bundle->ncp.mp.active ? 1106 dl->bundle->ncp.mp.server.socket.sun_path : ""); 1107 }; 1108 1109 if (rad_put_string(r->cx.rad, RAD_USER_NAME, ac->user_name) != 0 || 1110 rad_put_int(r->cx.rad, RAD_SERVICE_TYPE, RAD_FRAMED) != 0 || 1111 rad_put_int(r->cx.rad, RAD_FRAMED_PROTOCOL, RAD_PPP) != 0) { 1112 log_Printf(LogERROR, "rad_put: %s\n", rad_strerror(r->cx.rad)); 1113 rad_close(r->cx.rad); 1114 return; 1115 } 1116 switch (ac->proto) { 1117 case PROTO_IPCP: 1118 if (rad_put_addr(r->cx.rad, RAD_FRAMED_IP_ADDRESS, 1119 ac->peer.ip.addr) != 0 || 1120 rad_put_addr(r->cx.rad, RAD_FRAMED_IP_NETMASK, 1121 ac->peer.ip.mask) != 0) { 1122 log_Printf(LogERROR, "rad_put: %s\n", rad_strerror(r->cx.rad)); 1123 rad_close(r->cx.rad); 1124 return; 1125 } 1126 break; 1127 #ifndef NOINET6 1128 case PROTO_IPV6CP: 1129 if (rad_put_attr(r->cx.rad, RAD_FRAMED_INTERFACE_ID, ac->peer.ipv6.ifid, 1130 sizeof(ac->peer.ipv6.ifid)) != 0) { 1131 log_Printf(LogERROR, "rad_put_attr: %s\n", rad_strerror(r->cx.rad)); 1132 rad_close(r->cx.rad); 1133 return; 1134 } 1135 if (r->ipv6prefix) { 1136 /* 1137 * Since PPP doesn't delegate an IPv6 prefix to a peer, 1138 * Framed-IPv6-Prefix may be not used, actually. 1139 */ 1140 if (rad_put_attr(r->cx.rad, RAD_FRAMED_IPV6_PREFIX, r->ipv6prefix, 1141 sizeof(struct in6_addr) + 2) != 0) { 1142 log_Printf(LogERROR, "rad_put_attr: %s\n", rad_strerror(r->cx.rad)); 1143 rad_close(r->cx.rad); 1144 return; 1145 } 1146 } 1147 break; 1148 #endif 1149 default: 1150 /* We don't log any protocol specific information */ 1151 break; 1152 } 1153 1154 if ((mac_addr = getenv("HISMACADDR")) != NULL && 1155 rad_put_string(r->cx.rad, RAD_CALLING_STATION_ID, mac_addr) != 0) { 1156 log_Printf(LogERROR, "rad_put: %s\n", rad_strerror(r->cx.rad)); 1157 rad_close(r->cx.rad); 1158 return; 1159 } 1160 1161 if (gethostname(hostname, sizeof hostname) != 0) 1162 log_Printf(LogERROR, "rad_put: gethostname(): %s\n", strerror(errno)); 1163 else { 1164 #if 0 1165 if ((hp = gethostbyname(hostname)) != NULL) { 1166 hostaddr.s_addr = *(u_long *)hp->h_addr; 1167 if (rad_put_addr(r->cx.rad, RAD_NAS_IP_ADDRESS, hostaddr) != 0) { 1168 log_Printf(LogERROR, "rad_put: rad_put_string: %s\n", 1169 rad_strerror(r->cx.rad)); 1170 rad_close(r->cx.rad); 1171 return; 1172 } 1173 } 1174 #endif 1175 if (rad_put_string(r->cx.rad, RAD_NAS_IDENTIFIER, hostname) != 0) { 1176 log_Printf(LogERROR, "rad_put: rad_put_string: %s\n", 1177 rad_strerror(r->cx.rad)); 1178 rad_close(r->cx.rad); 1179 return; 1180 } 1181 } 1182 1183 radius_put_physical_details(r->cx.rad, dl->physical); 1184 1185 if (rad_put_int(r->cx.rad, RAD_ACCT_STATUS_TYPE, acct_type) != 0 || 1186 rad_put_string(r->cx.rad, RAD_ACCT_SESSION_ID, ac->session_id) != 0 || 1187 rad_put_string(r->cx.rad, RAD_ACCT_MULTI_SESSION_ID, 1188 ac->multi_session_id) != 0 || 1189 rad_put_int(r->cx.rad, RAD_ACCT_DELAY_TIME, 0) != 0) { 1190 /* XXX ACCT_DELAY_TIME should be increased each time a packet is waiting */ 1191 log_Printf(LogERROR, "rad_put: %s\n", rad_strerror(r->cx.rad)); 1192 rad_close(r->cx.rad); 1193 return; 1194 } 1195 1196 if (acct_type == RAD_STOP || acct_type == RAD_ALIVE) 1197 /* Show some statistics */ 1198 if (rad_put_int(r->cx.rad, RAD_ACCT_INPUT_OCTETS, stats->OctetsIn % UINT32_MAX) != 0 || 1199 rad_put_int(r->cx.rad, RAD_ACCT_INPUT_GIGAWORDS, stats->OctetsIn / UINT32_MAX) != 0 || 1200 rad_put_int(r->cx.rad, RAD_ACCT_INPUT_PACKETS, stats->PacketsIn) != 0 || 1201 rad_put_int(r->cx.rad, RAD_ACCT_OUTPUT_OCTETS, stats->OctetsOut % UINT32_MAX) != 0 || 1202 rad_put_int(r->cx.rad, RAD_ACCT_OUTPUT_GIGAWORDS, stats->OctetsOut / UINT32_MAX) != 0 || 1203 rad_put_int(r->cx.rad, RAD_ACCT_OUTPUT_PACKETS, stats->PacketsOut) 1204 != 0 || 1205 rad_put_int(r->cx.rad, RAD_ACCT_SESSION_TIME, throughput_uptime(stats)) 1206 != 0) { 1207 log_Printf(LogERROR, "rad_put: %s\n", rad_strerror(r->cx.rad)); 1208 rad_close(r->cx.rad); 1209 return; 1210 } 1211 1212 if (log_IsKept(LogPHASE) || log_IsKept(LogRADIUS)) { 1213 char *what; 1214 int level; 1215 1216 switch (acct_type) { 1217 case RAD_START: 1218 what = "START"; 1219 level = log_IsKept(LogPHASE) ? LogPHASE : LogRADIUS; 1220 break; 1221 case RAD_STOP: 1222 what = "STOP"; 1223 level = log_IsKept(LogPHASE) ? LogPHASE : LogRADIUS; 1224 break; 1225 case RAD_ALIVE: 1226 what = "ALIVE"; 1227 level = LogRADIUS; 1228 break; 1229 default: 1230 what = "<unknown>"; 1231 level = log_IsKept(LogPHASE) ? LogPHASE : LogRADIUS; 1232 break; 1233 } 1234 log_Printf(level, "Radius(acct): %s data sent\n", what); 1235 } 1236 1237 r->cx.auth = NULL; /* Not valid for accounting requests */ 1238 if ((got = rad_init_send_request(r->cx.rad, &r->cx.fd, &tv))) 1239 radius_Process(r, got); 1240 else { 1241 log_Printf(LogDEBUG, "Using radius_Timeout [%p]\n", radius_Timeout); 1242 r->cx.timer.load = tv.tv_usec / TICKUNIT + tv.tv_sec * SECTICKS; 1243 r->cx.timer.func = radius_Timeout; 1244 r->cx.timer.name = "radius acct"; 1245 r->cx.timer.arg = r; 1246 timer_Start(&r->cx.timer); 1247 } 1248 } 1249 1250 /* 1251 * How do things look at the moment ? 1252 */ 1253 void 1254 radius_Show(struct radius *r, struct prompt *p) 1255 { 1256 prompt_Printf(p, " Radius config: %s", 1257 *r->cfg.file ? r->cfg.file : "none"); 1258 if (r->valid) { 1259 prompt_Printf(p, "\n IP: %s\n", inet_ntoa(r->ip)); 1260 prompt_Printf(p, " Netmask: %s\n", inet_ntoa(r->mask)); 1261 prompt_Printf(p, " MTU: %lu\n", r->mtu); 1262 prompt_Printf(p, " VJ: %sabled\n", r->vj ? "en" : "dis"); 1263 prompt_Printf(p, " Message: %s\n", r->repstr ? r->repstr : ""); 1264 prompt_Printf(p, " MPPE Enc Policy: %s\n", 1265 radius_policyname(r->mppe.policy)); 1266 prompt_Printf(p, " MPPE Enc Types: %s\n", 1267 radius_typesname(r->mppe.types)); 1268 prompt_Printf(p, " MPPE Recv Key: %seceived\n", 1269 r->mppe.recvkey ? "R" : "Not r"); 1270 prompt_Printf(p, " MPPE Send Key: %seceived\n", 1271 r->mppe.sendkey ? "R" : "Not r"); 1272 prompt_Printf(p, " MS-CHAP2-Response: %s\n", 1273 r->msrepstr ? r->msrepstr : ""); 1274 prompt_Printf(p, " Error Message: %s\n", r->errstr ? r->errstr : ""); 1275 if (r->routes) 1276 route_ShowSticky(p, r->routes, " Routes", 16); 1277 #ifndef NOINET6 1278 if (r->ipv6routes) 1279 route_ShowSticky(p, r->ipv6routes, " IPv6 Routes", 16); 1280 #endif 1281 } else 1282 prompt_Printf(p, " (not authenticated)\n"); 1283 } 1284 1285 static void 1286 radius_alive(void *v) 1287 { 1288 struct bundle *bundle = (struct bundle *)v; 1289 1290 timer_Stop(&bundle->radius.alive.timer); 1291 bundle->radius.alive.timer.load = bundle->radius.alive.interval * SECTICKS; 1292 if (bundle->radius.alive.timer.load) { 1293 radius_Account(&bundle->radius, &bundle->radacct, 1294 bundle->links, RAD_ALIVE, &bundle->ncp.ipcp.throughput); 1295 timer_Start(&bundle->radius.alive.timer); 1296 } 1297 } 1298 1299 void 1300 radius_StartTimer(struct bundle *bundle) 1301 { 1302 if (bundle->radius.cfg.file && bundle->radius.alive.interval) { 1303 bundle->radius.alive.timer.func = radius_alive; 1304 bundle->radius.alive.timer.name = "radius alive"; 1305 bundle->radius.alive.timer.load = bundle->radius.alive.interval * SECTICKS; 1306 bundle->radius.alive.timer.arg = bundle; 1307 radius_alive(bundle); 1308 } 1309 } 1310 1311 void 1312 radius_StopTimer(struct radius *r) 1313 { 1314 timer_Stop(&r->alive.timer); 1315 } 1316