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