Annotation of embedaddon/mpd/src/radsrv.c, revision 1.1
1.1 ! misho 1:
! 2: /*
! 3: * radsrv.c
! 4: *
! 5: * Written by Alexander Motin <mav@FreeBSD.org>
! 6: */
! 7:
! 8: #include "ppp.h"
! 9: #include "radsrv.h"
! 10: #include "util.h"
! 11: #include <radlib.h>
! 12: #include <radlib_vs.h>
! 13:
! 14: #ifdef RAD_COA_REQUEST
! 15:
! 16: /*
! 17: * DEFINITIONS
! 18: */
! 19:
! 20: /* Set menu options */
! 21: enum {
! 22: SET_OPEN,
! 23: SET_CLOSE,
! 24: SET_SELF,
! 25: SET_PEER,
! 26: SET_DISABLE,
! 27: SET_ENABLE
! 28: };
! 29:
! 30:
! 31: /*
! 32: * INTERNAL FUNCTIONS
! 33: */
! 34:
! 35: static int RadsrvSetCommand(Context ctx, int ac, char *av[], void *arg);
! 36:
! 37: /*
! 38: * GLOBAL VARIABLES
! 39: */
! 40:
! 41: const struct cmdtab RadsrvSetCmds[] = {
! 42: { "open", "Open the radsrv" ,
! 43: RadsrvSetCommand, NULL, 2, (void *) SET_OPEN },
! 44: { "close", "Close the radsrv" ,
! 45: RadsrvSetCommand, NULL, 2, (void *) SET_CLOSE },
! 46: { "self {ip} [{port}]", "Set radsrv ip and port" ,
! 47: RadsrvSetCommand, NULL, 2, (void *) SET_SELF },
! 48: { "peer {ip} {secret}", "Set peer ip and secret" ,
! 49: RadsrvSetCommand, NULL, 2, (void *) SET_PEER },
! 50: { "enable [opt ...]", "Enable radsrv option" ,
! 51: RadsrvSetCommand, NULL, 2, (void *) SET_ENABLE },
! 52: { "disable [opt ...]", "Disable radsrv option" ,
! 53: RadsrvSetCommand, NULL, 2, (void *) SET_DISABLE },
! 54: { NULL },
! 55: };
! 56:
! 57:
! 58: /*
! 59: * INTERNAL VARIABLES
! 60: */
! 61:
! 62: static const struct confinfo gConfList[] = {
! 63: { 0, RADSRV_DISCONNECT, "disconnect" },
! 64: { 0, RADSRV_COA, "coa" },
! 65: { 0, 0, NULL },
! 66: };
! 67:
! 68: /*
! 69: * RadsrvInit()
! 70: */
! 71:
! 72: int
! 73: RadsrvInit(Radsrv w)
! 74: {
! 75: /* setup radsrv-defaults */
! 76: memset(w, 0, sizeof(*w));
! 77:
! 78: Enable(&w->options, RADSRV_DISCONNECT);
! 79: Enable(&w->options, RADSRV_COA);
! 80:
! 81: ParseAddr(DEFAULT_RADSRV_IP, &w->addr, ALLOW_IPV4);
! 82: w->port = DEFAULT_RADSRV_PORT;
! 83:
! 84: return (0);
! 85: }
! 86:
! 87: static void
! 88: RadsrvEvent(int type, void *cookie)
! 89: {
! 90: Radsrv w = (Radsrv)cookie;
! 91: const void *data;
! 92: size_t len;
! 93: int res, result, found, err, anysesid, l;
! 94: Bund B;
! 95: Link L;
! 96: char *tmpval;
! 97: char *username = NULL, *called = NULL, *calling = NULL, *sesid = NULL;
! 98: char *msesid = NULL, *link = NULL, *bundle = NULL, *iface = NULL;
! 99: int nasport = -1, serv_type = 0, ifindex = -1, i;
! 100: u_int session_timeout = -1, idle_timeout = -1, acct_update = -1;
! 101: struct in_addr ip = { -1 };
! 102: struct in_addr nas_ip = { -1 };
! 103: char buf[64];
! 104: u_int32_t vendor;
! 105: u_char *state = NULL;
! 106: int state_len = 0;
! 107: int authentic = 0;
! 108: #if defined(USE_NG_BPF) || defined(USE_IPFW)
! 109: struct acl **acls, *acls1;
! 110: char *acl, *acl1, *acl2, *acl3;
! 111: #endif
! 112: #ifdef USE_IPFW
! 113: struct acl *acl_rule = NULL; /* ipfw rules */
! 114: struct acl *acl_pipe = NULL; /* ipfw pipes */
! 115: struct acl *acl_queue = NULL; /* ipfw queues */
! 116: struct acl *acl_table = NULL; /* ipfw tables */
! 117: #endif
! 118: #ifdef USE_NG_BPF
! 119: struct acl *acl_filters[ACL_FILTERS]; /* mpd's internal bpf filters */
! 120: struct acl *acl_limits[ACL_DIRS]; /* traffic limits based on mpd's filters */
! 121: char std_acct[ACL_DIRS][ACL_NAME_LEN]; /* Names of ACL returned in standard accounting */
! 122:
! 123: bzero(acl_filters, sizeof(acl_filters));
! 124: bzero(acl_limits, sizeof(acl_limits));
! 125: bzero(std_acct, sizeof(std_acct));
! 126: #endif
! 127: result = rad_receive_request(w->handle);
! 128: if (result < 0) {
! 129: Log(LG_ERR, ("radsrv: request receive error: %d", result));
! 130: return;
! 131: }
! 132: switch (result) {
! 133: case RAD_DISCONNECT_REQUEST:
! 134: if (!Enabled(&w->options, RADSRV_DISCONNECT)) {
! 135: Log(LG_ERR, ("radsrv: DISCONNECT request, support disabled"));
! 136: rad_create_response(w->handle, RAD_DISCONNECT_NAK);
! 137: rad_put_int(w->handle, RAD_ERROR_CAUSE, 501);
! 138: rad_send_response(w->handle);
! 139: return;
! 140: }
! 141: Log(LG_ERR, ("radsrv: DISCONNECT request"));
! 142: break;
! 143: case RAD_COA_REQUEST:
! 144: if (!Enabled(&w->options, RADSRV_COA)) {
! 145: Log(LG_ERR, ("radsrv: CoA request, support disabled"));
! 146: rad_create_response(w->handle, RAD_COA_NAK);
! 147: rad_put_int(w->handle, RAD_ERROR_CAUSE, 501);
! 148: rad_send_response(w->handle);
! 149: return;
! 150: }
! 151: Log(LG_ERR, ("radsrv: CoA request"));
! 152: break;
! 153: default:
! 154: Log(LG_ERR, ("radsrv: unsupported request: %d", result));
! 155: return;
! 156: }
! 157: anysesid = 0;
! 158: while ((res = rad_get_attr(w->handle, &data, &len)) > 0) {
! 159: switch (res) {
! 160: case RAD_USER_NAME:
! 161: anysesid = 1;
! 162: username = rad_cvt_string(data, len);
! 163: Log(LG_RADIUS2, ("radsrv: Got RAD_USER_NAME: %s",
! 164: username));
! 165: break;
! 166: case RAD_NAS_IP_ADDRESS:
! 167: nas_ip = rad_cvt_addr(data);
! 168: Log(LG_RADIUS2, ("radsrv: Got RAD_NAS_IP_ADDRESS: %s ",
! 169: inet_ntoa(nas_ip)));
! 170: break;
! 171: case RAD_SERVICE_TYPE:
! 172: serv_type = rad_cvt_int(data);
! 173: Log(LG_RADIUS2, ("radsrv: Got RAD_SERVICE_TYPE: %d",
! 174: serv_type));
! 175: break;
! 176: case RAD_STATE:
! 177: tmpval = Bin2Hex(data, len);
! 178: Log(LG_RADIUS2, ("radsrv: Get RAD_STATE: 0x%s", tmpval));
! 179: Freee(tmpval);
! 180: state_len = len;
! 181: if (state != NULL)
! 182: Freee(state);
! 183: state = Mdup(MB_RADSRV, data, len);
! 184: break;
! 185: case RAD_CALLED_STATION_ID:
! 186: anysesid = 1;
! 187: called = rad_cvt_string(data, len);
! 188: Log(LG_RADIUS2, ("radsrv: Got RAD_CALLED_STATION_ID: %s ",
! 189: called));
! 190: break;
! 191: case RAD_CALLING_STATION_ID:
! 192: anysesid = 1;
! 193: calling = rad_cvt_string(data, len);
! 194: Log(LG_RADIUS2, ("radsrv: Got RAD_CALLING_STATION_ID: %s ",
! 195: calling));
! 196: break;
! 197: case RAD_ACCT_SESSION_ID:
! 198: anysesid = 1;
! 199: sesid = rad_cvt_string(data, len);
! 200: Log(LG_RADIUS2, ("radsrv: Got RAD_ACCT_SESSION_ID: %s ",
! 201: sesid));
! 202: break;
! 203: case RAD_ACCT_MULTI_SESSION_ID:
! 204: anysesid = 1;
! 205: msesid = rad_cvt_string(data, len);
! 206: Log(LG_RADIUS2, ("radsrv: Got RAD_ACCT_MULTI_SESSION_ID: %s ",
! 207: msesid));
! 208: break;
! 209: case RAD_FRAMED_IP_ADDRESS:
! 210: anysesid = 1;
! 211: ip = rad_cvt_addr(data);
! 212: Log(LG_RADIUS2, ("radsrv: Got RAD_FRAMED_IP_ADDRESS: %s ",
! 213: inet_ntoa(ip)));
! 214: break;
! 215: case RAD_NAS_PORT:
! 216: anysesid = 1;
! 217: nasport = rad_cvt_int(data);
! 218: Log(LG_RADIUS2, ("radsrv: Got RAD_NAS_PORT: %d ",
! 219: nasport));
! 220: break;
! 221: case RAD_SESSION_TIMEOUT:
! 222: session_timeout = rad_cvt_int(data);
! 223: Log(LG_RADIUS2, ("radsrv: Got RAD_SESSION_TIMEOUT: %u ",
! 224: session_timeout));
! 225: break;
! 226: case RAD_IDLE_TIMEOUT:
! 227: idle_timeout = rad_cvt_int(data);
! 228: Log(LG_RADIUS2, ("radsrv: Got RAD_IDLE_TIMEOUT: %u ",
! 229: idle_timeout));
! 230: break;
! 231: case RAD_ACCT_INTERIM_INTERVAL:
! 232: acct_update = rad_cvt_int(data);
! 233: Log(LG_RADIUS2, ("radsrv: Got RAD_ACCT_INTERIM_INTERVAL: %u ",
! 234: acct_update));
! 235: break;
! 236: case RAD_MESSAGE_AUTHENTIC:
! 237: Log(LG_RADIUS2, ("radsrv: Got RAD_MESSAGE_AUTHENTIC"));
! 238: authentic = 1;
! 239: break;
! 240: case RAD_VENDOR_SPECIFIC:
! 241: if ((res = rad_get_vendor_attr(&vendor, &data, &len)) == -1) {
! 242: Log(LG_RADIUS, ("radsrv: Get vendor attr failed: %s ",
! 243: rad_strerror(w->handle)));
! 244: break;
! 245: }
! 246: switch (vendor) {
! 247: case RAD_VENDOR_MPD:
! 248: if (res == RAD_MPD_LINK) {
! 249: if (link)
! 250: free(link);
! 251: link = rad_cvt_string(data, len);
! 252: Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_LINK: %s",
! 253: link));
! 254: anysesid = 1;
! 255: break;
! 256: } else if (res == RAD_MPD_BUNDLE) {
! 257: if (bundle)
! 258: free(bundle);
! 259: bundle = rad_cvt_string(data, len);
! 260: Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_BINDLE: %s",
! 261: bundle));
! 262: anysesid = 1;
! 263: break;
! 264: } else if (res == RAD_MPD_IFACE) {
! 265: if (iface)
! 266: free(iface);
! 267: iface = rad_cvt_string(data, len);
! 268: Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_IFACE: %s",
! 269: iface));
! 270: anysesid = 1;
! 271: break;
! 272: } else if (res == RAD_MPD_IFACE_INDEX) {
! 273: ifindex = rad_cvt_int(data);
! 274: Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_IFACE_INDEX: %d",
! 275: ifindex));
! 276: anysesid = 1;
! 277: break;
! 278: } else
! 279: #ifdef USE_IPFW
! 280: if (res == RAD_MPD_RULE) {
! 281: acl1 = acl = rad_cvt_string(data, len);
! 282: Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_RULE: %s",
! 283: acl));
! 284: acls = &acl_rule;
! 285: } else if (res == RAD_MPD_PIPE) {
! 286: acl1 = acl = rad_cvt_string(data, len);
! 287: Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_PIPE: %s",
! 288: acl));
! 289: acls = &acl_pipe;
! 290: } else if (res == RAD_MPD_QUEUE) {
! 291: acl1 = acl = rad_cvt_string(data, len);
! 292: Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_QUEUE: %s",
! 293: acl));
! 294: acls = &acl_queue;
! 295: } else if (res == RAD_MPD_TABLE) {
! 296: acl1 = acl = rad_cvt_string(data, len);
! 297: Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_TABLE: %s",
! 298: acl));
! 299: acls = &acl_table;
! 300: } else if (res == RAD_MPD_TABLE_STATIC) {
! 301: acl1 = acl = rad_cvt_string(data, len);
! 302: Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_TABLE_STATIC: %s",
! 303: acl));
! 304: acls = &acl_table;
! 305: } else
! 306: #endif /* USE_IPFW */
! 307: #ifdef USE_NG_BPF
! 308: if (res == RAD_MPD_FILTER) {
! 309: acl1 = acl = rad_cvt_string(data, len);
! 310: Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_FILTER: %s",
! 311: acl));
! 312: acl2 = strsep(&acl1, "#");
! 313: i = atol(acl2);
! 314: if (i <= 0 || i > ACL_FILTERS) {
! 315: Log(LG_RADIUS, ("radsrv: Wrong filter number: %i", i));
! 316: free(acl);
! 317: break;
! 318: }
! 319: acls = &(acl_filters[i - 1]);
! 320: } else if (res == RAD_MPD_LIMIT) {
! 321: acl1 = acl = rad_cvt_string(data, len);
! 322: Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_LIMIT: %s",
! 323: acl));
! 324: acl2 = strsep(&acl1, "#");
! 325: if (strcasecmp(acl2, "in") == 0) {
! 326: i = 0;
! 327: } else if (strcasecmp(acl2, "out") == 0) {
! 328: i = 1;
! 329: } else {
! 330: Log(LG_ERR, ("radsrv: Wrong limit direction: '%s'",
! 331: acl2));
! 332: free(acl);
! 333: break;
! 334: }
! 335: acls = &(acl_limits[i]);
! 336: } else if (res == RAD_MPD_INPUT_ACCT) {
! 337: tmpval = rad_cvt_string(data, len);
! 338: Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_INPUT_ACCT: %s",
! 339: tmpval));
! 340: strlcpy(std_acct[0], tmpval, sizeof(std_acct[0]));
! 341: free(tmpval);
! 342: break;
! 343: } else if (res == RAD_MPD_OUTPUT_ACCT) {
! 344: tmpval = rad_cvt_string(data, len);
! 345: Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_OUTPUT_ACCT: %s",
! 346: tmpval));
! 347: strlcpy(std_acct[1], tmpval, sizeof(std_acct[1]));
! 348: free(tmpval);
! 349: break;
! 350: } else
! 351: #endif /* USE_NG_BPF */
! 352: {
! 353: Log(LG_RADIUS2, ("radsrv: Dropping MPD vendor specific attribute: %d",
! 354: res));
! 355: break;
! 356: }
! 357: #if defined(USE_NG_BPF) || defined(USE_IPFW)
! 358: if (acl1 == NULL) {
! 359: Log(LG_ERR, ("radsrv: Incorrect acl!"));
! 360: free(acl);
! 361: break;
! 362: }
! 363:
! 364: acl3 = acl1;
! 365: strsep(&acl3, "=");
! 366: acl2 = acl1;
! 367: strsep(&acl2, "#");
! 368: i = atol(acl1);
! 369: if (i <= 0) {
! 370: Log(LG_ERR, ("radsrv: Wrong acl number: %i", i));
! 371: free(acl);
! 372: break;
! 373: }
! 374: if ((acl3 == NULL) || (acl3[0] == 0)) {
! 375: Log(LG_ERR, ("radsrv: Wrong acl"));
! 376: free(acl);
! 377: break;
! 378: }
! 379: acls1 = Malloc(MB_AUTH, sizeof(struct acl) + strlen(acl3));
! 380: if (res != RAD_MPD_TABLE_STATIC) {
! 381: acls1->number = i;
! 382: acls1->real_number = 0;
! 383: } else {
! 384: acls1->number = 0;
! 385: acls1->real_number = i;
! 386: }
! 387: if (acl2)
! 388: strlcpy(acls1->name, acl2, sizeof(acls1->name));
! 389: strcpy(acls1->rule, acl3);
! 390: while ((*acls != NULL) && ((*acls)->number < acls1->number))
! 391: acls = &((*acls)->next);
! 392:
! 393: if (*acls == NULL) {
! 394: acls1->next = NULL;
! 395: } else if (((*acls)->number == acls1->number) &&
! 396: (res != RAD_MPD_TABLE) &&
! 397: (res != RAD_MPD_TABLE_STATIC)) {
! 398: Log(LG_ERR, ("radsrv: Duplicate acl"));
! 399: Freee(acls1);
! 400: free(acl);
! 401: break;
! 402: } else {
! 403: acls1->next = *acls;
! 404: }
! 405: *acls = acls1;
! 406:
! 407: free(acl);
! 408: break;
! 409: #endif /* USE_NG_BPF or USE_IPFW */
! 410:
! 411: default:
! 412: Log(LG_RADIUS2, ("radsrv: Dropping vendor %d attribute: %d ",
! 413: vendor, res));
! 414: break;
! 415: }
! 416: break;
! 417: default:
! 418: Log(LG_RADIUS2, ("radsrv: Unknown attribute: %d ",
! 419: res));
! 420: break;
! 421: }
! 422: }
! 423: err = 0;
! 424: if (w->addr.u.ip4.s_addr != 0 && nas_ip.s_addr != -1 && w->addr.u.ip4.s_addr != nas_ip.s_addr) {
! 425: Log(LG_ERR, ("radsrv: incorrect NAS-IP-Address"));
! 426: err = 403;
! 427: } else if (anysesid == 0) {
! 428: Log(LG_ERR, ("radsrv: request without session identification"));
! 429: err = 402;
! 430: } else if (serv_type != 0) {
! 431: Log(LG_ERR, ("radsrv: Service-Type attribute not supported"));
! 432: err = 405;
! 433: }
! 434: if (err) {
! 435: if (result == RAD_DISCONNECT_REQUEST)
! 436: rad_create_response(w->handle, RAD_DISCONNECT_NAK);
! 437: else
! 438: rad_create_response(w->handle, RAD_COA_NAK);
! 439: rad_put_int(w->handle, RAD_ERROR_CAUSE, err);
! 440: if (state != NULL)
! 441: rad_put_attr(w->handle, RAD_STATE, state, state_len);
! 442: if (authentic)
! 443: rad_put_message_authentic(w->handle);
! 444: rad_send_response(w->handle);
! 445: goto cleanup;
! 446: }
! 447: found = 0;
! 448: err = 503;
! 449: for (l = 0; l < gNumLinks; l++) {
! 450: if ((L = gLinks[l]) != NULL) {
! 451: B = L->bund;
! 452: if (nasport != -1 && nasport != l)
! 453: continue;
! 454: if (sesid && strcmp(sesid, L->session_id))
! 455: continue;
! 456: if (link && strcmp(link, L->name))
! 457: continue;
! 458: if (msesid && strcmp(msesid, L->msession_id))
! 459: continue;
! 460: if (username && strcmp(username, L->lcp.auth.params.authname))
! 461: continue;
! 462: if (called && !PhysGetCalledNum(L, buf, sizeof(buf)) &&
! 463: strcmp(called, buf))
! 464: continue;
! 465: if (calling && !PhysGetCallingNum(L, buf, sizeof(buf)) &&
! 466: strcmp(calling, buf))
! 467: continue;
! 468: if (bundle && (!B || strcmp(bundle, B->name)))
! 469: continue;
! 470: if (iface && (!B || strcmp(iface, B->iface.ifname)))
! 471: continue;
! 472: if (ifindex >= 0 && (!B || ifindex != B->iface.ifindex))
! 473: continue;
! 474: if (ip.s_addr != -1 && (!B ||
! 475: ip.s_addr != B->iface.peer_addr.u.ip4.s_addr))
! 476: continue;
! 477:
! 478: Log(LG_RADIUS2, ("radsrv: Matched link: %s",
! 479: L->name));
! 480: if (L->tmpl) {
! 481: Log(LG_ERR, ("radsrv: Impossible to affect template"));
! 482: err = 504;
! 483: continue;
! 484: }
! 485: found++;
! 486:
! 487: if (result == RAD_DISCONNECT_REQUEST) {
! 488: RecordLinkUpDownReason(NULL, L, 0, STR_MANUALLY, NULL);
! 489: LinkClose(L);
! 490: } else { /* CoA */
! 491: if (B && B->iface.up && !B->iface.dod) {
! 492: if (B->iface.ip_up)
! 493: IfaceIpIfaceDown(B);
! 494: if (B->iface.ipv6_up)
! 495: IfaceIpv6IfaceDown(B);
! 496: IfaceDown(B);
! 497: }
! 498: #ifdef USE_IPFW
! 499: ACLDestroy(L->lcp.auth.params.acl_rule);
! 500: ACLDestroy(L->lcp.auth.params.acl_pipe);
! 501: ACLDestroy(L->lcp.auth.params.acl_queue);
! 502: ACLDestroy(L->lcp.auth.params.acl_table);
! 503: L->lcp.auth.params.acl_rule = NULL;
! 504: L->lcp.auth.params.acl_pipe = NULL;
! 505: L->lcp.auth.params.acl_queue = NULL;
! 506: L->lcp.auth.params.acl_table = NULL;
! 507: ACLCopy(acl_rule, &L->lcp.auth.params.acl_rule);
! 508: ACLCopy(acl_pipe, &L->lcp.auth.params.acl_pipe);
! 509: ACLCopy(acl_queue, &L->lcp.auth.params.acl_queue);
! 510: ACLCopy(acl_table, &L->lcp.auth.params.acl_table);
! 511: #endif /* USE_IPFW */
! 512: #ifdef USE_NG_BPF
! 513: for (i = 0; i < ACL_FILTERS; i++) {
! 514: ACLDestroy(L->lcp.auth.params.acl_filters[i]);
! 515: L->lcp.auth.params.acl_filters[i] = NULL;
! 516: ACLCopy(acl_filters[i], &L->lcp.auth.params.acl_filters[i]);
! 517: }
! 518: for (i = 0; i < ACL_DIRS; i++) {
! 519: ACLDestroy(L->lcp.auth.params.acl_limits[i]);
! 520: L->lcp.auth.params.acl_limits[i] = NULL;
! 521: ACLCopy(acl_limits[i], &L->lcp.auth.params.acl_limits[i]);
! 522: }
! 523: strcpy(L->lcp.auth.params.std_acct[0], std_acct[0]);
! 524: strcpy(L->lcp.auth.params.std_acct[1], std_acct[1]);
! 525: #endif
! 526: if (session_timeout != -1)
! 527: L->lcp.auth.params.session_timeout = session_timeout;
! 528: if (idle_timeout != -1)
! 529: L->lcp.auth.params.idle_timeout = idle_timeout;
! 530: if (acct_update != -1) {
! 531: L->lcp.auth.params.acct_update = acct_update;
! 532: /* Stop accounting update timer if running. */
! 533: TimerStop(&L->lcp.auth.acct_timer);
! 534: if (B) {
! 535: /* Start accounting update timer if needed. */
! 536: u_int updateInterval;
! 537: if (L->lcp.auth.params.acct_update > 0)
! 538: updateInterval = L->lcp.auth.params.acct_update;
! 539: else
! 540: updateInterval = L->lcp.auth.conf.acct_update;
! 541: if (updateInterval > 0) {
! 542: TimerInit(&L->lcp.auth.acct_timer, "AuthAccountTimer",
! 543: updateInterval * SECONDS, AuthAccountTimeout, L);
! 544: TimerStartRecurring(&L->lcp.auth.acct_timer);
! 545: }
! 546: }
! 547: }
! 548: if (B && B->iface.up && !B->iface.dod) {
! 549: authparamsDestroy(&B->params);
! 550: authparamsCopy(&L->lcp.auth.params,&B->params);
! 551: if (B->iface.ip_up)
! 552: IfaceIpIfaceUp(B, 1);
! 553: if (B->iface.ipv6_up)
! 554: IfaceIpv6IfaceUp(B, 1);
! 555: IfaceUp(B, 1);
! 556: }
! 557: }
! 558: }
! 559: }
! 560: if (result == RAD_DISCONNECT_REQUEST) {
! 561: if (found) {
! 562: rad_create_response(w->handle, RAD_DISCONNECT_ACK);
! 563: } else {
! 564: rad_create_response(w->handle, RAD_DISCONNECT_NAK);
! 565: rad_put_int(w->handle, RAD_ERROR_CAUSE, err);
! 566: }
! 567: } else {
! 568: if (found) {
! 569: rad_create_response(w->handle, RAD_COA_ACK);
! 570: } else {
! 571: rad_create_response(w->handle, RAD_COA_NAK);
! 572: rad_put_int(w->handle, RAD_ERROR_CAUSE, err);
! 573: }
! 574: }
! 575: if (state != NULL)
! 576: rad_put_attr(w->handle, RAD_STATE, state, state_len);
! 577: if (authentic)
! 578: rad_put_message_authentic(w->handle);
! 579: rad_send_response(w->handle);
! 580:
! 581: cleanup:
! 582: if (username)
! 583: free(username);
! 584: if (called)
! 585: free(called);
! 586: if (calling)
! 587: free(calling);
! 588: if (sesid)
! 589: free(sesid);
! 590: if (msesid)
! 591: free(msesid);
! 592: if (link)
! 593: free(link);
! 594: if (bundle)
! 595: free(bundle);
! 596: if (iface)
! 597: free(iface);
! 598: if (state != NULL)
! 599: Freee(state);
! 600: #ifdef USE_IPFW
! 601: ACLDestroy(acl_rule);
! 602: ACLDestroy(acl_pipe);
! 603: ACLDestroy(acl_queue);
! 604: ACLDestroy(acl_table);
! 605: #endif /* USE_IPFW */
! 606: #ifdef USE_NG_BPF
! 607: for (i = 0; i < ACL_FILTERS; i++)
! 608: ACLDestroy(acl_filters[i]);
! 609: for (i = 0; i < ACL_DIRS; i++)
! 610: ACLDestroy(acl_limits[i]);
! 611: #endif /* USE_NG_BPF */
! 612: }
! 613:
! 614: /*
! 615: * RadsrvOpen()
! 616: */
! 617:
! 618: int
! 619: RadsrvOpen(Radsrv w)
! 620: {
! 621: char addrstr[INET6_ADDRSTRLEN];
! 622: struct sockaddr_in sin;
! 623: struct radiusclient_conf *s;
! 624:
! 625: if (w->handle) {
! 626: Log(LG_ERR, ("radsrv: radsrv already running"));
! 627: return (-1);
! 628: }
! 629:
! 630: if ((w->fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
! 631: Perror("%s: Cannot create socket", __FUNCTION__);
! 632: return (-1);
! 633: }
! 634: memset(&sin, 0, sizeof sin);
! 635: sin.sin_len = sizeof sin;
! 636: sin.sin_family = AF_INET;
! 637: sin.sin_addr = w->addr.u.ip4;
! 638: sin.sin_port = htons(w->port);
! 639: if (bind(w->fd, (const struct sockaddr *)&sin,
! 640: sizeof sin) == -1) {
! 641: Log(LG_ERR, ("%s: bind: %s", __FUNCTION__, strerror(errno)));
! 642: close(w->fd);
! 643: w->fd = -1;
! 644: return (-1);
! 645: }
! 646:
! 647: if (!(w->handle = rad_server_open(w->fd))) {
! 648: Log(LG_ERR, ("%s: rad_server_open error", __FUNCTION__));
! 649: close(w->fd);
! 650: w->fd = -1;
! 651: return(-1);
! 652: }
! 653:
! 654: EventRegister(&w->event, EVENT_READ, w->fd,
! 655: EVENT_RECURRING, RadsrvEvent, w);
! 656:
! 657: s = w->clients;
! 658: while (s) {
! 659: Log(LG_RADIUS2, ("radsrv: Adding client %s", s->hostname));
! 660: if (rad_add_server (w->handle, s->hostname,
! 661: 0, s->sharedsecret, 0, 0) == -1) {
! 662: Log(LG_RADIUS, ("radsrv: Adding client error: %s",
! 663: rad_strerror(w->handle)));
! 664: }
! 665: s = s->next;
! 666: }
! 667:
! 668: Log(LG_ERR, ("radsrv: listening on %s %d",
! 669: u_addrtoa(&w->addr,addrstr,sizeof(addrstr)), w->port));
! 670: return (0);
! 671: }
! 672:
! 673: /*
! 674: * RadsrvClose()
! 675: */
! 676:
! 677: int
! 678: RadsrvClose(Radsrv w)
! 679: {
! 680:
! 681: if (!w->handle) {
! 682: Log(LG_ERR, ("radsrv: radsrv is not running"));
! 683: return (-1);
! 684: }
! 685: EventUnRegister(&w->event);
! 686: rad_close(w->handle);
! 687: w->handle = NULL;
! 688:
! 689: Log(LG_ERR, ("radsrv: stop listening"));
! 690: return (0);
! 691: }
! 692:
! 693: /*
! 694: * RadsrvStat()
! 695: */
! 696:
! 697: int
! 698: RadsrvStat(Context ctx, int ac, char *av[], void *arg)
! 699: {
! 700: Radsrv w = &gRadsrv;
! 701: char addrstr[64];
! 702: struct radiusclient_conf *client;
! 703:
! 704: Printf("Radsrv configuration:\r\n");
! 705: Printf("\tState : %s\r\n", w->handle ? "OPENED" : "CLOSED");
! 706: Printf("\tSelf : %s %d\r\n",
! 707: u_addrtoa(&w->addr,addrstr,sizeof(addrstr)), w->port);
! 708: Printf("\tPeer:\r\n");
! 709: client = w->clients;
! 710: while (client) {
! 711: Printf("\t %s ********\r\n", client->hostname);
! 712: client = client->next;
! 713: }
! 714: Printf("Radsrv options:\r\n");
! 715: OptStat(ctx, &w->options, gConfList);
! 716:
! 717: return (0);
! 718: }
! 719:
! 720: /*
! 721: * RadsrvSetCommand()
! 722: */
! 723:
! 724: static int
! 725: RadsrvSetCommand(Context ctx, int ac, char *av[], void *arg)
! 726: {
! 727: Radsrv w = &gRadsrv;
! 728: int port, count;
! 729: struct radiusclient_conf *peer, *t_peer;
! 730:
! 731: switch ((intptr_t)arg) {
! 732:
! 733: case SET_OPEN:
! 734: RadsrvOpen(w);
! 735: break;
! 736:
! 737: case SET_CLOSE:
! 738: RadsrvClose(w);
! 739: break;
! 740:
! 741: case SET_ENABLE:
! 742: EnableCommand(ac, av, &w->options, gConfList);
! 743: break;
! 744:
! 745: case SET_DISABLE:
! 746: DisableCommand(ac, av, &w->options, gConfList);
! 747: break;
! 748:
! 749: case SET_SELF:
! 750: if (ac < 1 || ac > 2)
! 751: return(-1);
! 752:
! 753: if (!ParseAddr(av[0],&w->addr, ALLOW_IPV4))
! 754: Error("Bogus IP address given %s", av[0]);
! 755:
! 756: if (ac == 2) {
! 757: port = strtol(av[1], NULL, 10);
! 758: if (port < 1 || port > 65535)
! 759: Error("Bogus port given %s", av[1]);
! 760: w->port=port;
! 761: }
! 762: break;
! 763:
! 764: case SET_PEER:
! 765: if (ac != 2)
! 766: return(-1);
! 767:
! 768: count = 0;
! 769: for ( t_peer = w->clients ; t_peer ;
! 770: t_peer = t_peer->next) {
! 771: count++;
! 772: }
! 773: if (count > RADSRV_MAX_SERVERS) {
! 774: Error("cannot configure more than %d peers",
! 775: RADSRV_MAX_SERVERS);
! 776: }
! 777: if (strlen(av[0]) > MAXHOSTNAMELEN-1)
! 778: Error("Hostname too long. > %d char.", MAXHOSTNAMELEN-1);
! 779: if (strlen(av[1]) > 127)
! 780: Error("Shared Secret too long. > 127 char.");
! 781:
! 782: peer = Malloc(MB_RADSRV, sizeof(*peer));
! 783: peer->hostname = Mstrdup(MB_RADSRV, av[0]);
! 784: peer->sharedsecret = Mstrdup(MB_RADSRV, av[1]);
! 785: peer->next = w->clients;
! 786: w->clients = peer;
! 787: break;
! 788:
! 789: default:
! 790: return(-1);
! 791:
! 792: }
! 793:
! 794: return 0;
! 795: }
! 796:
! 797: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>